diff --git a/src/choice.rs b/src/choice.rs index 18c953d..ec01c0d 100644 --- a/src/choice.rs +++ b/src/choice.rs @@ -147,12 +147,15 @@ where #[cfg(test)] mod tests { use super::*; - use crate::combinators::one_or_more; + use crate::combinators::repeated; use crate::primitives::literal; #[test] fn test_choice() { - let p = choice2(literal("gnostika").to(1), one_or_more(literal(" ")).to(2)); + let p = choice2( + literal("gnostika").to(1), + repeated(literal(" ")).at_least(1).to(2), + ); assert_eq!(p.parse("gnostika twentynine"), Ok((1, " twentynine"))); } } diff --git a/src/combinators.rs b/src/combinators.rs index 4b3ef25..38d0efb 100644 --- a/src/combinators.rs +++ b/src/combinators.rs @@ -1,4 +1,4 @@ -use crate::parser::Parser; +use crate::parser::{BoxedParser, ParseResult, Parser}; pub fn optional
(parser: P) -> impl Parser, E>
where
@@ -23,6 +23,78 @@ where
}
}
+pub struct Repeated<'a, I, O>
+where
+ I: Clone,
+{
+ inner_parser: BoxedParser<'a, I, O, I>,
+ at_least: Option (parser: P) -> impl Parser, I>
where
P: Parser,
@@ -60,7 +132,6 @@ where
#[cfg(test)]
mod tests {
use super::*;
- use crate::combinators::one_or_more;
use crate::primitives::literal;
#[test]
@@ -72,7 +143,7 @@ mod tests {
#[test]
fn test_one_or_more() {
- let p = one_or_more(literal("bongo "));
+ let p = repeated(literal("bongo ")).at_least(1);
let input = "bongo bongo bongo bongo bongo ";
let (output, rest) = p.parse(input).unwrap();
diff --git a/src/parser.rs b/src/parser.rs
index ff64f07..86c9908 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -60,7 +60,7 @@ pub struct BoxedParser<'a, I, O, E> {
}
impl<'a, I, O, E> BoxedParser<'a, I, O, E> {
- fn new (inner: P) -> Self
+ pub(crate) fn new (inner: P) -> Self
where
P: Parser + 'a,
{