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