oni_comb_parser/combinator/
many.rs1use alloc::vec::Vec;
2
3use crate::fail::{Fail, PResult};
4use crate::input::Input;
5use crate::parser::Parser;
6
7pub struct Many<P> {
8 pub(crate) parser: P,
9}
10
11impl<I, P> Parser<I> for Many<P>
12where
13 I: Input,
14 P: Parser<I>,
15{
16 type Error = P::Error;
17 type Output = Vec<P::Output>;
18
19 #[inline]
20 fn parse_next(&mut self, input: &mut I) -> PResult<Self::Output, Self::Error> {
21 let mut items = Vec::new();
22 loop {
23 let cp = input.checkpoint();
24 match self.parser.parse_next(input) {
25 Ok(v) => {
26 if input.checkpoint() == cp {
27 return Err(Fail::ZeroProgress);
28 }
29 items.push(v);
30 }
31 Err(Fail::Backtrack(_)) => {
32 input.reset(cp);
33 return Ok(items);
34 }
35 Err(Fail::Cut(e)) => return Err(Fail::Cut(e)),
36 Err(Fail::Incomplete) => return Err(Fail::Incomplete),
37 Err(Fail::ZeroProgress) => return Err(Fail::ZeroProgress),
38 }
39 }
40 }
41}