From 304a360608947e04f8d20caf017cafef9b51c08a Mon Sep 17 00:00:00 2001 From: p6nj Date: Thu, 7 Nov 2024 21:12:27 -0500 Subject: [PATCH 1/2] avoid parsing if string is empty --- src/bng/score.rs | 2 +- src/bng/score/de.rs | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/bng/score.rs b/src/bng/score.rs index 4aadc1e..84ba46c 100644 --- a/src/bng/score.rs +++ b/src/bng/score.rs @@ -33,7 +33,7 @@ pub use de::*; use super::Expression as Instruction; -#[derive(Deref, From)] +#[derive(Deref, From, Default)] #[cfg_attr(debug_assertions, derive(Serialize, Debug))] pub struct Atoms(Vec); diff --git a/src/bng/score/de.rs b/src/bng/score/de.rs index 1745d76..e9c16a0 100644 --- a/src/bng/score/de.rs +++ b/src/bng/score/de.rs @@ -2,7 +2,7 @@ use derive_new::new; use nom::{ character::complete::one_of, combinator::all_consuming, - multi::many0, + multi::{many0, many1}, sequence::{preceded, terminated}, Parser, }; @@ -108,7 +108,11 @@ impl<'de> Deserialize<'de> for Atoms { const FIELDS: &[&str] = &["notes", "sheet"]; let NotesSheet { notes, sheet } = deserializer.deserialize_struct("NotesSheet", FIELDS, NotesSheetVisitor)?; - flat_atom_parser_mapper::(&sheet, flat_atom_parser(¬es)) + if sheet.is_empty() { + Ok(Default::default()) + } else { + flat_atom_parser_mapper::(&sheet, flat_atom_parser(¬es)) + } } } @@ -128,7 +132,7 @@ where P: Parser<&'a str, FlatAtom, nom::error::Error<&'a str>>, { all_consuming(terminated( - many0(preceded(maybe_yml_str_space(), parser)), + many1(preceded(maybe_yml_str_space(), parser)), maybe_yml_str_space(), ))(input) .map_err(nom_err_message) From 78d7c493bb2e89e811cf1ab3b4f789e1cb369ab9 Mon Sep 17 00:00:00 2001 From: p6nj Date: Thu, 7 Nov 2024 21:43:32 -0500 Subject: [PATCH 2/2] simplify Deserialize impl for Atoms --- src/bng/score/de.rs | 49 +-------------------------------------------- 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/src/bng/score/de.rs b/src/bng/score/de.rs index e9c16a0..aa97ecd 100644 --- a/src/bng/score/de.rs +++ b/src/bng/score/de.rs @@ -60,54 +60,7 @@ impl<'de> Deserialize<'de> for Atoms { 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(self, mut seq: A) -> Result - 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(self, mut map: A) -> Result - 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 NotesSheet { notes, sheet } = NotesSheet::deserialize(deserializer)?; if sheet.is_empty() { Ok(Default::default()) } else {