Skip to main content

oni_comb_parser/combinator/
many1.rs

1use 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}