cleaning my room

This commit is contained in:
Ponj 2024-11-04 22:26:33 -05:00
parent a06e0a1d02
commit 93067b3010
Signed by: p6nj
GPG key ID: 6FED68D87C479A59
2 changed files with 129 additions and 107 deletions

View file

@ -27,7 +27,9 @@ use thiserror::Error;
use utils::{inflate, InflateError}; use utils::{inflate, InflateError};
mod lex; mod lex;
mod ser;
mod utils; mod utils;
pub use ser::*;
use super::Expression as Instruction; use super::Expression as Instruction;
@ -35,113 +37,6 @@ use super::Expression as Instruction;
#[cfg_attr(debug_assertions, derive(Serialize, Debug))] #[cfg_attr(debug_assertions, derive(Serialize, Debug))]
pub struct Atoms(Vec<Atom>); pub struct Atoms(Vec<Atom>);
#[derive(Debug, Error)]
enum AtomsSerializeError {
#[error("sheet parsing error: {0}")]
Parsing(String),
#[error("sheet semantics: {0}")]
Inflation(#[from] InflateError),
}
fn nom_err_message(e: nom::Err<nom::error::Error<&str>>) -> String {
match e {
nom::Err::Incomplete(needed) => format!(
"input is incomplete, needed {} byte(s) more",
match needed {
nom::Needed::Unknown => "?".to_string(),
nom::Needed::Size(s) => s.to_string(),
}
),
nom::Err::Error(e) | nom::Err::Failure(e) => format!(
"got error code {code:#?} at \"{input}\"",
code = e.code,
input = e.input
),
}
}
impl<'de> Deserialize<'de> for Atoms {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Notes,
Sheet,
}
#[derive(Deserialize, new)]
struct NotesSheet {
notes: String,
sheet: String,
}
struct NotesSheetVisitor;
impl<'de> Visitor<'de> for NotesSheetVisitor {
type Value = NotesSheet;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a \"notes\" field and a \"sheet\" field")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let notes = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
let sheet = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(1, &self))?;
Ok(NotesSheet::new(notes, sheet))
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: de::MapAccess<'de>,
{
let mut notes = None;
let mut sheet = None;
while let Some(key) = map.next_key()? {
match key {
Field::Notes => {
if notes.is_some() {
return Err(de::Error::duplicate_field("notes"));
}
notes = Some(map.next_value()?);
}
Field::Sheet => {
if sheet.is_some() {
return Err(de::Error::duplicate_field("sheet"));
}
sheet = Some(map.next_value()?);
}
}
}
let notes = notes.ok_or_else(|| de::Error::missing_field("notes"))?;
let sheet = sheet.ok_or_else(|| de::Error::missing_field("sheet"))?;
Ok(NotesSheet::new(notes, sheet))
}
}
const FIELDS: &[&str] = &["notes", "sheet"];
let NotesSheet { notes, sheet } =
deserializer.deserialize_struct("NotesSheet", FIELDS, NotesSheetVisitor)?;
let maybe_yml_str_space = || many0(one_of(" \t\r"));
let x = all_consuming(terminated(
many0(preceded(maybe_yml_str_space(), flat_atom_parser(&notes))),
maybe_yml_str_space(),
))(dbg!(&sheet))
.map_err(nom_err_message)
.map_err(AtomsSerializeError::Parsing)
.map_err(de::Error::custom)
.and_then(|(_, v)| {
inflate(v)
.map_err(AtomsSerializeError::from)
.map_err(de::Error::custom)
})
.map(Atoms);
x
}
}
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))] #[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
pub enum Atom { pub enum Atom {
Note(u8), Note(u8),

127
src/bng/score/ser.rs Normal file
View file

@ -0,0 +1,127 @@
use de::Deserializer;
use nom::Parser;
use super::*;
#[derive(Debug, Error)]
enum AtomsSerializeError {
#[error("sheet parsing error: {0}")]
Parsing(String),
#[error("sheet semantics: {0}")]
Inflation(#[from] InflateError),
}
fn nom_err_message(e: nom::Err<nom::error::Error<&str>>) -> String {
match e {
nom::Err::Incomplete(needed) => format!(
"input is incomplete, needed {} byte(s) more",
match needed {
nom::Needed::Unknown => "?".to_string(),
nom::Needed::Size(s) => s.to_string(),
}
),
nom::Err::Error(e) | nom::Err::Failure(e) => format!(
"got error code {code:#?} at \"{input}\"",
code = e.code,
input = e.input
),
}
}
impl<'de> Deserialize<'de> for Atoms {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Notes,
Sheet,
}
#[derive(Deserialize, new)]
struct NotesSheet {
notes: String,
sheet: String,
}
struct NotesSheetVisitor;
impl<'de> Visitor<'de> for NotesSheetVisitor {
type Value = NotesSheet;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a \"notes\" field and a \"sheet\" field")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let notes = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
let sheet = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(1, &self))?;
Ok(NotesSheet::new(notes, sheet))
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: de::MapAccess<'de>,
{
let mut notes = None;
let mut sheet = None;
while let Some(key) = map.next_key()? {
match key {
Field::Notes => {
if notes.is_some() {
return Err(de::Error::duplicate_field("notes"));
}
notes = Some(map.next_value()?);
}
Field::Sheet => {
if sheet.is_some() {
return Err(de::Error::duplicate_field("sheet"));
}
sheet = Some(map.next_value()?);
}
}
}
let notes = notes.ok_or_else(|| de::Error::missing_field("notes"))?;
let sheet = sheet.ok_or_else(|| de::Error::missing_field("sheet"))?;
Ok(NotesSheet::new(notes, sheet))
}
}
const FIELDS: &[&str] = &["notes", "sheet"];
let NotesSheet { notes, sheet } =
deserializer.deserialize_struct("NotesSheet", FIELDS, NotesSheetVisitor)?;
flat_atom_parser_mapper::<D, _>(&sheet, flat_atom_parser(&notes))
}
}
fn maybe_yml_str_space<'a, E>() -> impl Parser<&'a str, Vec<char>, E>
where
E: nom::error::ParseError<&'a str>,
{
many0(one_of(" \t\r"))
}
fn flat_atom_parser_mapper<'a, 'de, D, P>(
input: &'a str,
parser: P,
) -> Result<Atoms, <D as Deserializer<'de>>::Error>
where
D: serde::Deserializer<'de>,
P: Parser<&'a str, FlatAtom, nom::error::Error<&'a str>>,
{
all_consuming(terminated(
many0(preceded(maybe_yml_str_space(), parser)),
maybe_yml_str_space(),
))(input)
.map_err(nom_err_message)
.map_err(AtomsSerializeError::Parsing)
.map_err(de::Error::custom)
.and_then(|(_, v)| {
inflate(v)
.map_err(AtomsSerializeError::from)
.map_err(de::Error::custom)
})
.map(Atoms)
}