utils/parser/
combinator.rs

1use crate::array::ArrayVec;
2use crate::input::{InputError, MapWithInputExt};
3use crate::parser::then::Then2;
4use crate::parser::{ParseError, ParseResult, Parser};
5
6#[derive(Copy, Clone)]
7pub struct Map<P, F> {
8    pub(super) parser: P,
9    pub(super) map_fn: F,
10}
11
12impl<P: Parser, F: for<'i> Fn(P::Output<'i>) -> O, O> Parser for Map<P, F> {
13    type Output<'i> = O;
14    type Then<T: Parser> = Then2<Self, T>;
15
16    #[inline]
17    fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
18        match self.parser.parse(input) {
19            Ok((v, remaining)) => Ok(((self.map_fn)(v), remaining)),
20            Err(e) => Err(e),
21        }
22    }
23}
24
25#[derive(Copy, Clone)]
26pub struct MapResult<P, F> {
27    pub(super) parser: P,
28    pub(super) map_fn: F,
29}
30
31impl<P: Parser, F: for<'i> Fn(P::Output<'i>) -> Result<O, &'static str>, O> Parser
32    for MapResult<P, F>
33{
34    type Output<'i> = O;
35    type Then<T: Parser> = Then2<Self, T>;
36
37    #[inline]
38    fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
39        match self.parser.parse(input) {
40            Ok((v, remaining)) => match (self.map_fn)(v) {
41                Ok(mapped) => Ok((mapped, remaining)),
42                Err(e) => Err((ParseError::Custom(e), input)),
43            },
44            Err(e) => Err(e),
45        }
46    }
47}
48
49#[derive(Copy, Clone)]
50pub struct Optional<P> {
51    pub(super) parser: P,
52}
53impl<P: Parser> Parser for Optional<P> {
54    type Output<'i> = Option<P::Output<'i>>;
55    type Then<T: Parser> = Then2<Self, T>;
56
57    #[inline]
58    fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
59        match self.parser.parse(input) {
60            Ok((v, remaining)) => Ok((Some(v), remaining)),
61            Err(_) => Ok((None, input)),
62        }
63    }
64}
65
66#[derive(Copy, Clone)]
67pub struct RepeatN<const N: usize, P, S> {
68    pub(super) parser: P,
69    pub(super) separator: S,
70}
71impl<const N: usize, P: for<'i> Parser<Output<'i>: Copy + Default>, S: Parser> Parser
72    for RepeatN<N, P, S>
73{
74    type Output<'i> = [P::Output<'i>; N];
75    type Then<T: Parser> = Then2<Self, T>;
76
77    #[inline]
78    fn parse<'i>(&self, mut input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
79        let mut output = [P::Output::default(); N];
80        for (i, item) in output.iter_mut().enumerate() {
81            match self.parser.parse(input) {
82                Ok((v, remaining)) => {
83                    *item = v;
84                    input = remaining;
85                }
86                Err(e) => return Err(e),
87            }
88
89            if i < N - 1 {
90                match self.separator.parse(input) {
91                    Ok((_, remaining)) => input = remaining,
92                    Err(e) => return Err(e),
93                }
94            }
95        }
96        Ok((output, input))
97    }
98}
99
100#[derive(Copy, Clone)]
101pub struct RepeatArrayVec<const N: usize, P, S> {
102    pub(super) parser: P,
103    pub(super) separator: S,
104    pub(super) min_elements: usize,
105}
106impl<const N: usize, P: for<'i> Parser<Output<'i>: Copy + Default>, S: Parser> Parser
107    for RepeatArrayVec<N, P, S>
108{
109    type Output<'i> = ArrayVec<P::Output<'i>, N>;
110    type Then<T: Parser> = Then2<Self, T>;
111
112    #[inline]
113    fn parse<'i>(&self, mut input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
114        let mut output = ArrayVec::new();
115
116        let err = loop {
117            let (v, remaining) = match self.parser.parse(input) {
118                Ok(v) => v,
119                Err(err) => break err,
120            };
121
122            let consumed = input.len() - remaining.len();
123            assert!(consumed > 0, "parsing item consumed no input");
124
125            if output.push(v).is_err() {
126                return Err((ParseError::ExpectedLessItems(N), input));
127            }
128            input = remaining;
129
130            match self.separator.parse(input) {
131                Ok((_, remaining)) => input = remaining,
132                Err(err) => break err,
133            }
134        };
135
136        if output.len() >= self.min_elements {
137            Ok((output, input))
138        } else {
139            Err(err)
140        }
141    }
142}
143
144#[derive(Copy, Clone)]
145pub struct RepeatVec<P, S> {
146    pub(super) parser: P,
147    pub(super) separator: S,
148    pub(super) min_elements: usize,
149}
150impl<P: Parser, S: Parser> RepeatVec<P, S> {
151    #[inline]
152    fn helper<'i>(
153        &self,
154        mut input: &'i [u8],
155        consume_all: bool,
156    ) -> ParseResult<'i, Vec<P::Output<'i>>> {
157        let mut output = Vec::new();
158
159        let err = loop {
160            let (v, remaining) = match self.parser.parse(input) {
161                Ok(v) => v,
162                Err(err) => break err,
163            };
164
165            let consumed = input.len() - remaining.len();
166            assert!(consumed > 0, "parsing item consumed no input");
167
168            // When parsing the complete input, after parsing the first item use the proportion of
169            // consumed bytes for one item to reserve capacity for the output vec
170            if consume_all && output.is_empty() {
171                output.reserve(((remaining.len() / consumed) * 7 / 5) + 2);
172            }
173
174            output.push(v);
175            input = remaining;
176
177            match self.separator.parse(input) {
178                Ok((_, remaining)) => input = remaining,
179                Err(err) => break err,
180            }
181        };
182
183        if (consume_all && !input.is_empty()) || output.len() < self.min_elements {
184            // Return the last parsing error if this parser should consume the entire input and it
185            // hasn't, or if the minimum number of elements isn't met.
186            Err(err)
187        } else {
188            Ok((output, input))
189        }
190    }
191}
192impl<P: Parser, S: Parser> Parser for RepeatVec<P, S> {
193    type Output<'i> = Vec<P::Output<'i>>;
194    type Then<T: Parser> = Then2<Self, T>;
195
196    #[inline]
197    fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
198        self.helper(input, false)
199    }
200
201    // Override the default implementation to set consume_all to true
202    fn parse_complete<'i>(&self, input: &'i str) -> Result<Self::Output<'i>, InputError> {
203        match self.helper(input.as_bytes(), true).map_with_input(input)? {
204            (v, []) => Ok(v),
205            (_, remaining) => Err(InputError::new(input, remaining, "expected end of input")),
206        }
207    }
208}
209
210#[derive(Copy, Clone)]
211pub struct Or<A, B> {
212    pub(super) first: A,
213    pub(super) second: B,
214}
215impl<A: Parser, B: for<'i> Parser<Output<'i> = A::Output<'i>>> Parser for Or<A, B> {
216    type Output<'i> = A::Output<'i>;
217    type Then<T: Parser> = Then2<Self, T>;
218
219    #[inline(always)]
220    #[expect(
221        clippy::inline_always,
222        reason = "required for parsing of long or chains to be inlined"
223    )]
224    fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
225        match self.first.parse(input) {
226            Ok(v) => Ok(v),
227            Err((err1, remaining1)) => match self.second.parse(input) {
228                Ok(v) => Ok(v),
229                Err((err2, remaining2)) => {
230                    // Return error from the parser which processed further, or the first if equal
231                    Err(if remaining1.len() <= remaining2.len() {
232                        (err1, remaining1)
233                    } else {
234                        (err2, remaining2)
235                    })
236                }
237            },
238        }
239    }
240}
241
242#[derive(Copy, Clone)]
243pub struct WithConsumed<P> {
244    pub(super) parser: P,
245}
246impl<P: Parser> Parser for WithConsumed<P> {
247    type Output<'i> = (P::Output<'i>, &'i [u8]);
248    type Then<T: Parser> = Then2<Self, T>;
249
250    #[inline]
251    fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
252        match self.parser.parse(input) {
253            Ok((v, remaining)) => Ok(((v, &input[..input.len() - remaining.len()]), remaining)),
254            Err(e) => Err(e),
255        }
256    }
257}
258
259#[derive(Copy, Clone)]
260pub struct WithPrefix<A, B> {
261    pub(super) parser: A,
262    pub(super) prefix: B,
263}
264impl<A: Parser, B: Parser> Parser for WithPrefix<A, B> {
265    type Output<'i> = A::Output<'i>;
266    type Then<T: Parser> = Then2<Self, T>;
267
268    #[inline]
269    fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
270        match self.prefix.parse(input) {
271            Ok((_, remaining)) => self.parser.parse(remaining),
272            Err(e) => Err(e),
273        }
274    }
275}
276
277#[derive(Copy, Clone)]
278pub struct WithSuffix<A, B> {
279    pub(super) parser: A,
280    pub(super) suffix: B,
281}
282impl<A: Parser, B: Parser> Parser for WithSuffix<A, B> {
283    type Output<'i> = A::Output<'i>;
284    type Then<T: Parser> = Then2<Self, T>;
285
286    #[inline]
287    fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
288        match self.parser.parse(input) {
289            Ok((v, remaining1)) => match self.suffix.parse(remaining1) {
290                Ok((_, remaining2)) => Ok((v, remaining2)),
291                Err(e) => Err(e),
292            },
293            Err(e) => Err(e),
294        }
295    }
296}