choice combinator
This commit is contained in:
parent
00d866f2a1
commit
8002b83a86
29
src/lib.rs
29
src/lib.rs
@ -19,6 +19,17 @@ trait Parser<I, O, E> {
|
||||
BoxedParser::new(map(self, map_fn))
|
||||
}
|
||||
|
||||
fn to<'a, O2>(self, item: O2) -> BoxedParser<'a, I, O2, E>
|
||||
where
|
||||
Self: Sized + 'a,
|
||||
I: 'a,
|
||||
O: 'a,
|
||||
O2: Clone + 'a,
|
||||
E: 'a,
|
||||
{
|
||||
self.map(move |_| item.clone())
|
||||
}
|
||||
|
||||
fn then<'a, P, O2>(self, next_parser: P) -> BoxedParser<'a, I, (O, O2), E>
|
||||
where
|
||||
Self: Sized + 'a,
|
||||
@ -182,6 +193,18 @@ fn any_char(input: &str) -> ParseResult<&str, char, &str> {
|
||||
}
|
||||
}
|
||||
|
||||
fn choice<P1, P2, I, O, E>(parser1: P1, parser2: P2) -> impl Parser<I, O, E>
|
||||
where
|
||||
P1: Parser<I, O, E>,
|
||||
P2: Parser<I, O, E>,
|
||||
I: Copy,
|
||||
{
|
||||
move |input| match parser1.parse(input) {
|
||||
ok @ Ok(..) => ok,
|
||||
Err(_e) => parser2.parse(input),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -229,4 +252,10 @@ mod tests {
|
||||
let p = pred(any_char, |c| *c == 'f');
|
||||
assert_eq!(p.parse("frog"), Ok(('f', "rog")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_choice() {
|
||||
let p = choice(literal("gnostika").to(1), one_or_more(literal(" ")).to(2));
|
||||
assert_eq!(p.parse("gnostika twentynine"), Ok((1, " twentynine")));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user