diff --git a/src/lib.rs b/src/lib.rs index f0d0478..9f2e596 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,35 @@ where } } +pub trait ParserExtension: Parser { + fn map(self, map_fn: F) -> impl Parser + where + F: Fn(O) -> O2; + + fn to(self, item: O2) -> impl Parser; + fn then>(self, next: P) -> impl Parser; +} + +impl ParserExtension for T +where + T: Parser, +{ + fn map(self, map_fn: F) -> impl Parser + where + F: Fn(O) -> O2, + { + map(self, map_fn) + } + + fn to(self, item: O2) -> impl Parser { + self.map(move |_| item.clone()) + } + + fn then>(self, next: P) -> impl Parser { + seq2(self, next) + } +} + #[cfg(test)] mod tests { use super::*; @@ -60,17 +89,20 @@ mod tests { #[test] fn test_map() { - let parser = map( - seq2(literal("a"), literal("b")), - |(_a, _b): (&str, &str)| 59, - ); + let parser = + seq2(literal("a"), literal("b")).map(|(a, _b): (&str, &str)| (a.to_uppercase(), 59)); let output = parser.parse("abcd").unwrap(); - assert_eq!((59, "cd"), output); + assert_eq!((("A".to_owned(), 59), "cd"), output); + + let spaces = repeated(literal_char(' ')).at_least(1); + let parser = seq2(literal("lute"), spaces).to(500); + assert_eq!(parser.parse("lute "), Ok((500, ""))); + assert_eq!(parser.parse("lute"), Err(((), ""))); } #[test] fn test_combinators() { - let parser = seq2(map(repeated(literal_char('a')), |_| 10), literal_char('b')); + let parser = repeated(literal_char('a')).to(10).then(literal_char('b')); let output = parser.parse("aaaaaaaabcd").unwrap(); assert_eq! {((10, 'b'), "cd"), output}; }