oni_comb_parser/combinator/
sep_by.rs1use alloc::vec;
2use alloc::vec::Vec;
3
4use crate::fail::{Fail, PResult};
5use crate::input::Input;
6use crate::parser::Parser;
7
8pub struct SepBy0<P, S> {
9 pub(crate) parser: P,
10 pub(crate) sep: S,
11}
12
13impl<I, P, S> Parser<I> for SepBy0<P, S>
14where
15 I: Input,
16 P: Parser<I>,
17 S: Parser<I, Error = P::Error>,
18{
19 type Error = P::Error;
20 type Output = Vec<P::Output>;
21
22 #[inline]
23 fn parse_next(&mut self, input: &mut I) -> PResult<Self::Output, Self::Error> {
24 let mut items = Vec::new();
25
26 let cp = input.checkpoint();
28 match self.parser.parse_next(input) {
29 Ok(v) => items.push(v),
30 Err(Fail::Backtrack(_)) => {
31 input.reset(cp);
32 return Ok(items);
33 }
34 Err(e) => return Err(e),
35 }
36
37 loop {
39 let cp = input.checkpoint();
40 match self.sep.parse_next(input) {
41 Ok(_) => {}
42 Err(Fail::Backtrack(_)) => {
43 input.reset(cp);
44 break;
45 }
46 Err(e) => return Err(e),
47 }
48 match self.parser.parse_next(input) {
49 Ok(v) => items.push(v),
50 Err(Fail::Backtrack(_)) => {
51 input.reset(cp);
52 break;
53 }
54 Err(e) => return Err(e),
55 }
56 }
57
58 Ok(items)
59 }
60}
61
62pub struct SepBy1<P, S> {
63 pub(crate) parser: P,
64 pub(crate) sep: S,
65}
66
67impl<I, P, S> Parser<I> for SepBy1<P, S>
68where
69 I: Input,
70 P: Parser<I>,
71 S: Parser<I, Error = P::Error>,
72{
73 type Error = P::Error;
74 type Output = Vec<P::Output>;
75
76 #[inline]
77 fn parse_next(&mut self, input: &mut I) -> PResult<Self::Output, Self::Error> {
78 let first = self.parser.parse_next(input)?;
80 let mut items = vec![first];
81
82 loop {
84 let cp = input.checkpoint();
85 match self.sep.parse_next(input) {
86 Ok(_) => {}
87 Err(Fail::Backtrack(_)) => {
88 input.reset(cp);
89 break;
90 }
91 Err(e) => return Err(e),
92 }
93 match self.parser.parse_next(input) {
94 Ok(v) => items.push(v),
95 Err(Fail::Backtrack(_)) => {
96 input.reset(cp);
97 break;
98 }
99 Err(e) => return Err(e),
100 }
101 }
102
103 Ok(items)
104 }
105}