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))
|
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>
|
fn then<'a, P, O2>(self, next_parser: P) -> BoxedParser<'a, I, (O, O2), E>
|
||||||
where
|
where
|
||||||
Self: Sized + 'a,
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -229,4 +252,10 @@ mod tests {
|
|||||||
let p = pred(any_char, |c| *c == 'f');
|
let p = pred(any_char, |c| *c == 'f');
|
||||||
assert_eq!(p.parse("frog"), Ok(('f', "rog")));
|
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