diff --git a/src/lib.rs b/src/lib.rs index 7ac320b..a08a7fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,6 +49,30 @@ where } } +fn one_or_more(parser: P) -> impl Parser, I> +where + P: Parser, + I: Copy, +{ + move |mut input| { + let mut results = Vec::new(); + + if let Ok((result, rest)) = parser.parse(input) { + results.push(result); + input = rest; + } else { + return Err(input); + } + + while let Ok((item, rest)) = parser.parse(input) { + results.push(item); + input = rest; + } + + Ok((results, input)) + } +} + /// Parses a standard identifier in a programming language fn identifier(input: &str) -> ParseResult<&str, String, &str> { let mut chars = input.chars(); @@ -100,4 +124,11 @@ mod tests { let p = seq(identifier, seq(literal(" "), literal("ruts"))); assert_matches!(p.parse("fort1 ruts"), Ok((r, "")) if r.0 == "fort1" && r.1 == (" ", "ruts") ); } + + #[test] + fn test_one_or_more() { + let p = one_or_more(literal("bongo ")); + let input = "bongo bongo bongo bongo bongo "; + assert_matches!(p.parse(input), Ok((v, "")) if v.len() == 5); + } }