diff --git a/src/bng/score.rs b/src/bng/score.rs index 5e5e601..de6de55 100644 --- a/src/bng/score.rs +++ b/src/bng/score.rs @@ -1,4 +1,7 @@ -use std::num::{NonZeroU16, NonZeroU8}; +use std::{ + error::Error, + num::{NonZeroU16, NonZeroU8}, +}; use amplify::From; use anyhow::Context; @@ -8,8 +11,8 @@ use derived_deref::Deref; use lex::lexer::flat_atom_parser; use nom::{ branch::alt, - character::complete::char, - combinator::eof, + character::{complete::char, streaming::one_of}, + combinator::{all_consuming, eof}, multi::many0, sequence::{preceded, terminated}, }; @@ -34,12 +37,29 @@ pub struct Atoms(Vec); #[derive(Debug, Error)] enum AtomsSerializeError { - #[error("error while parsing with nom")] + #[error("sheet parsing error: {0}")] Parsing(String), - #[error("error while inflating flat atoms")] + #[error("sheet semantics: {0}")] Inflation(#[from] InflateError), } +fn nom_err_message(e: nom::Err>) -> String { + match e { + nom::Err::Incomplete(needed) => todo!(), + nom::Err::Error(e) => format!( + "got error code {code:#?} at character n°{charn} (after \"{before}\")", + code = e.code, + charn = e.input.len() + 1, + before = &e.input[e.input.len() + - option_env!("SHEET_BACKTRACE") + .and_then(|s| s.parse().ok()) + .unwrap_or(10usize) + + 1..] + ), + nom::Err::Failure(e) => todo!(), + } +} + impl<'de> Deserialize<'de> for Atoms { fn deserialize(deserializer: D) -> Result where @@ -104,14 +124,11 @@ impl<'de> Deserialize<'de> for Atoms { const FIELDS: &[&str] = &["notes", "sheet"]; let NotesSheet { notes, sheet } = deserializer.deserialize_struct("NotesSheet", FIELDS, NotesSheetVisitor)?; - let x = terminated( - many0(preceded( - many0(alt((char('\t'), char(' '), char('\n'), char('\r')))), - flat_atom_parser(¬es), - )), - eof, - )(&sheet) - .map_err(|e| e.to_string()) + let x = all_consuming(terminated( + many0(preceded(many0(one_of(" \t\r")), flat_atom_parser(¬es))), + many0(alt((char('\t'), char(' '), char('\n'), char('\r')))), + ))(dbg!(&sheet)) + .map_err(nom_err_message) .map_err(AtomsSerializeError::Parsing) .map_err(de::Error::custom) .and_then(|(_, v)| { diff --git a/src/main.rs b/src/main.rs index 8d4b51c..5a0fccc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use anyhow::Error; use bng::{BngFile, Channel, Expression, Instrument}; /// TODO: remove clap, use only a file or standard in use clap::Parser; @@ -9,7 +10,7 @@ use fasteval::Compiler; mod bng; mod cli; -fn main() -> Result<(), serde_yml::Error> { +fn main() -> Result<(), Error> { // println!("{}", option_env!("TEST").unwrap_or("ok")); let args = Cli::parse(); // #[cfg(debug_assertions)]