diff options
Diffstat (limited to 'src/lib.rs')
| -rw-r--r-- | src/lib.rs | 44 |
1 files changed, 44 insertions, 0 deletions
@@ -198,6 +198,10 @@ pub trait Parser<I: Input>: Sized { delimiter, } } + + fn find(self) -> impl ParserIter<I, Item = Self::Output> { + Find { parser: self } + } } pub trait ParserIter<I: Input> { @@ -951,6 +955,35 @@ where } } +struct Find<P> { + parser: P, +} + +impl<I, P> ParserIter<I> for Find<P> +where + I: Input, + P: Parser<I>, +{ + type Item = P::Output; + + fn next<OM: Mode, EM: Mode>( + &self, + mut it: InputIter<I>, + ) -> Option<ParserResult<I, Self::Item, OM, EM>> { + while !it.is_finished() { + it = match self.parser.run::<OM, EM, ()>(it.clone()) { + Ok((rest, output)) => return Some(Ok((rest, output))), + Err(_) => match take(1).check(it.clone()) { + Ok((rest, _)) => rest, + Err(_) => return None, + }, + }; + } + + None + } +} + pub fn eof<I>() -> impl Parser<I, Output = ()> where I: Input, @@ -1100,6 +1133,17 @@ mod test { } #[test] + fn test_find() { + let input = "hello world"; + let it = InputIter::new(input); + + assert_eq!( + alpha1().find().at_least(1).parse_finished(it).unwrap(), + vec!["hello", "world"] + ); + } + + #[test] #[cfg(feature = "regex")] fn test_regex_parser() { let it = InputIter::new("abc 123"); |
