From 17b9ab9e5beea3136068eb0e7399e86a8c37afdd Mon Sep 17 00:00:00 2001 From: "Francisco J. Sanchez" Date: Tue, 26 Dec 2023 20:33:29 +0100 Subject: [PATCH] release 0.11.0 --- CHANGELOG.md | 8 ++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- bindings/src/lib.rs | 7 ++----- src/aisle/mod.rs | 6 +++--- src/error.rs | 18 +++++++++++------- src/metadata.rs | 13 +++++++------ tests/general_tests.rs | 28 +++++++++++----------------- 8 files changed, 44 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2578e3..2e66ba0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased - ReleaseDate +## 0.11.0 - 2023-12-26 +### Breaking changes +- Remove `PassResult::take_output`. +- `Metadata::map_filtered` now returns an iterator instead of a copy of the map. + +### Fixed +- Implement `Clone` for `PassResult`. + ## 0.10.0 - 2023-12-17 ### Breaking changes - Reworked intermediate references. Index is gone, now you reference the step or diff --git a/Cargo.lock b/Cargo.lock index 94c2212..c298115 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,7 +252,7 @@ checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "cooklang" -version = "0.10.0" +version = "0.11.0" dependencies = [ "ariadne", "bitflags", diff --git a/Cargo.toml b/Cargo.toml index 33e1ab2..d25cda1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cooklang" -version = "0.10.0" +version = "0.11.0" edition = "2021" authors = ["Zheoni "] description = "Cooklang parser with opt-in extensions" diff --git a/bindings/src/lib.rs b/bindings/src/lib.rs index cbe087a..3190389 100644 --- a/bindings/src/lib.rs +++ b/bindings/src/lib.rs @@ -17,9 +17,7 @@ pub fn parse_recipe(input: String) -> CooklangRecipe { let converter = Converter::empty(); let mut parser = PullParser::new(&input, extensions); - let parsed = parse_events(&mut parser, &input, extensions, &converter, None) - .take_output() - .unwrap(); + let parsed = parse_events(&mut parser, &input, extensions, &converter, None).unwrap_output(); into_simple_recipe(&parsed) } @@ -40,8 +38,7 @@ pub fn parse_metadata(input: String) -> CooklangMetadata { None, ) .map(|c| c.metadata.map) - .take_output() - .unwrap(); + .unwrap_output(); // converting IndexMap into HashMap let _ = &(parsed).iter().for_each(|(key, value)| { diff --git a/src/aisle/mod.rs b/src/aisle/mod.rs index 6cb96d7..56cb63e 100644 --- a/src/aisle/mod.rs +++ b/src/aisle/mod.rs @@ -24,7 +24,7 @@ use parser::{AisleConfParser, Rule}; /// Represents a aisle configuration file /// -/// This type also implements [Serialize] and [Deserialize], so if you don't +/// This type also implements [`Serialize`] and [`Deserialize`], so if you don't /// like the cooklang shopping list format you can swap it with any [`serde`] /// format. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] @@ -47,7 +47,7 @@ pub struct Category<'a> { pub ingredients: Vec>, } -/// An ingredient belonging to a [Category] +/// An ingredient belonging to a [`Category`] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Ingredient<'a> { /// List of names of the ingredient @@ -149,7 +149,7 @@ pub fn write(conf: &AisleConf, mut write: impl std::io::Write) -> std::io::Resul Ok(()) } -/// Error generated by [parse]. +/// Error generated by [`parse`]. #[derive(Debug, Error, PartialEq, Eq)] pub enum AisleConfError { #[error("Error parsing input: {message}")] diff --git a/src/error.rs b/src/error.rs index f9bde10..bb21df9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -332,7 +332,7 @@ impl std::fmt::Display for SourceReport { impl std::error::Error for SourceReport {} /// Output from the different passes of the parsing process -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct PassResult { output: Option, report: SourceReport, @@ -348,7 +348,7 @@ impl PassResult { self.output.is_some() } - /// Check if the result has errors. + /// Get the report pub fn report(&self) -> &SourceReport { &self.report } @@ -366,6 +366,15 @@ impl PassResult { self.output.as_ref() } + /// Get the output only if it's valid + pub fn valid_output(&self) -> Option<&T> { + if self.is_valid() { + self.output() + } else { + None + } + } + /// Transform into a common Rust [`Result`] /// /// If the result is valid, the [`Ok`] variant holds the ouput and a @@ -384,11 +393,6 @@ impl PassResult { self.report } - /// Take the output, leaving `None` in the result - pub fn take_output(&mut self) -> Option { - self.output.take() - } - /// Transform into the ouput discarding errors/warnings pub fn into_output(self) -> Option { self.output diff --git a/src/metadata.rs b/src/metadata.rs index bb85241..ec35ab4 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -172,12 +172,13 @@ impl Metadata { Ok(()) } - /// Returns a copy of [`Self::map`] but with all *special* metadata values - /// removed - pub fn map_filtered(&self) -> IndexMap { - let mut new_map = self.map.clone(); - new_map.retain(|key, _| SpecialKey::from_str(key).is_err()); - new_map + /// Iterates over [`Self::map`] but with all *special* metadata values + /// skipped + pub fn map_filtered(&self) -> impl Iterator { + self.map + .iter() + .filter(|(key, _)| SpecialKey::from_str(key).is_err()) + .map(|(key, value)| (key.as_str(), value.as_str())) } } diff --git a/tests/general_tests.rs b/tests/general_tests.rs index 229854c..d3aa205 100644 --- a/tests/general_tests.rs +++ b/tests/general_tests.rs @@ -79,7 +79,7 @@ fn step_number(src: &str) -> Vec>> { Extensions::all() ^ Extensions::MULTILINE_STEPS, Default::default(), ); - let r = parser.parse(src).take_output().unwrap(); + let r = parser.parse(src).unwrap_output(); let numbers: Vec>> = r .sections .into_iter() @@ -111,14 +111,14 @@ fn empty_not_empty() { // should be the same with multiline and without let parser = CooklangParser::new(Extensions::all(), Default::default()); - let r = parser.parse(input).take_output().unwrap(); + let r = parser.parse(input).unwrap_output(); assert!(r.sections.is_empty()); let parser = CooklangParser::new( Extensions::all() ^ Extensions::MULTILINE_STEPS, Default::default(), ); - let r = parser.parse(input).take_output().unwrap(); + let r = parser.parse(input).unwrap_output(); assert!(r.sections.is_empty()); } @@ -139,14 +139,14 @@ fn empty_steps() { // should be the same with multiline and without let parser = CooklangParser::new(Extensions::all(), Default::default()); - let r = parser.parse(input).take_output().unwrap(); + let r = parser.parse(input).unwrap_output(); assert!(r.sections[0].content.is_empty()); let parser = CooklangParser::new( Extensions::all() ^ Extensions::MULTILINE_STEPS, Default::default(), ); - let r = parser.parse(input).take_output().unwrap(); + let r = parser.parse(input).unwrap_output(); assert!(r.sections[0].content.is_empty()); } @@ -160,7 +160,7 @@ fn whitespace_line_block_separator() { // should be the same with multiline and without let parser = CooklangParser::new(Extensions::all(), Default::default()); - let r = parser.parse(input).take_output().unwrap(); + let r = parser.parse(input).unwrap_output(); assert_eq!(r.sections[0].content.len(), 2); } @@ -173,7 +173,7 @@ fn single_line_no_separator() { = section "#}; let parser = CooklangParser::new(Extensions::all(), Default::default()); - let r = parser.parse(input).take_output().unwrap(); + let r = parser.parse(input).unwrap_output(); assert_eq!(r.sections.len(), 2); assert_eq!(r.sections[0].content.len(), 2); assert_eq!(r.sections[1].content.len(), 0); @@ -184,7 +184,7 @@ fn single_line_no_separator() { fn multiple_temperatures() { let input = "text 2ºC more text 150 F end text"; let parser = CooklangParser::new(Extensions::all(), Default::default()); - let r = parser.parse(input).take_output().unwrap(); + let r = parser.parse(input).unwrap_output(); assert_eq!(r.inline_quantities.len(), 2); assert_eq!(r.inline_quantities[0].value, 2.0.into()); assert_eq!(r.inline_quantities[0].unit_text(), Some("ºC")); @@ -220,7 +220,7 @@ fn no_steps_component_mode() { = section step "#}; - let r = cooklang::parse(input).take_output().unwrap(); + let r = cooklang::parse(input).unwrap_output(); assert_eq!(r.sections.len(), 1); assert_eq!(r.sections[0].name.as_deref(), Some("section")); assert!(matches!( @@ -233,19 +233,13 @@ fn no_steps_component_mode() { fn text_steps_extension() { let input = "> text"; - let r = CooklangParser::extended() - .parse(input) - .take_output() - .unwrap(); + let r = CooklangParser::extended().parse(input).unwrap_output(); assert!(matches!( r.sections[0].content.as_slice(), [Content::Text(_)] )); - let r = CooklangParser::canonical() - .parse(input) - .take_output() - .unwrap(); + let r = CooklangParser::canonical().parse(input).unwrap_output(); assert!(matches!( r.sections[0].content.as_slice(), [Content::Step(_)]