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