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<'i, P: Parser<'i>, F: Fn(P::Output) -> O, O> Parser<'i> for Map<P, F> {
13    type Output = O;
14    type Then<T: Parser<'i>> = Then2<Self, T>;
15
16    #[inline]
17    fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
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<'i, P: Parser<'i>, F: Fn(P::Output) -> Result<O, &'static str>, O> Parser<'i>
32    for MapResult<P, F>
33{
34    type Output = O;
35    type Then<T: Parser<'i>> = Then2<Self, T>;
36
37    #[inline]
38    fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
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<'i, P: Parser<'i>> Parser<'i> for Optional<P> {
54    type Output = Option<P::Output>;
55    type Then<T: Parser<'i>> = Then2<Self, T>;
56
57    #[inline]
58    fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
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<'i, const N: usize, P: Parser<'i, Output: Copy + Default>, S: Parser<'i>> Parser<'i>
72    for RepeatN<N, P, S>
73{
74    type Output = [P::Output; N];
75    type Then<T: Parser<'i>> = Then2<Self, T>;
76
77    #[inline]
78    fn parse(&self, mut input: &'i [u8]) -> ParseResult<'i, Self::Output> {
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<'i, const N: usize, P: Parser<'i, Output: Copy + Default>, S: Parser<'i>> Parser<'i>
107    for RepeatArrayVec<N, P, S>
108{
109    type Output = ArrayVec<P::Output, N>;
110    type Then<T: Parser<'i>> = Then2<Self, T>;
111
112    #[inline]
113    fn parse(&self, mut input: &'i [u8]) -> ParseResult<'i, Self::Output> {
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<'i, P: Parser<'i>, S: Parser<'i>> RepeatVec<P, S> {
151    #[inline]
152    fn helper(&self, mut input: &'i [u8], consume_all: bool) -> ParseResult<'i, Vec<P::Output>> {
153        let mut output = Vec::new();
154
155        let err = loop {
156            let (v, remaining) = match self.parser.parse(input) {
157                Ok(v) => v,
158                Err(err) => break err,
159            };
160
161            let consumed = input.len() - remaining.len();
162            assert!(consumed > 0, "parsing item consumed no input");
163
164            // When parsing the complete input, after parsing the first item use the proportion of
165            // consumed bytes for one item to reserve capacity for the output vec
166            if consume_all && output.is_empty() {
167                output.reserve(((remaining.len() / consumed) * 7 / 5) + 2);
168            }
169
170            output.push(v);
171            input = remaining;
172
173            match self.separator.parse(input) {
174                Ok((_, remaining)) => input = remaining,
175                Err(err) => break err,
176            }
177        };
178
179        if (consume_all && !input.is_empty()) || output.len() < self.min_elements {
180            // Return the last parsing error if this parser should consume the entire input and it
181            // hasn't, or if the minimum number of elements isn't met.
182            Err(err)
183        } else {
184            Ok((output, input))
185        }
186    }
187}
188impl<'i, P: Parser<'i>, S: Parser<'i>> Parser<'i> for RepeatVec<P, S> {
189    type Output = Vec<P::Output>;
190    type Then<T: Parser<'i>> = Then2<Self, T>;
191
192    #[inline]
193    fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
194        self.helper(input, false)
195    }
196
197    // Override the default implementation to set consume_all to true
198    fn parse_complete(&self, input: &'i str) -> Result<Self::Output, InputError> {
199        match self.helper(input.as_bytes(), true).map_with_input(input)? {
200            (v, []) => Ok(v),
201            (_, remaining) => Err(InputError::new(input, remaining, ParseError::ExpectedEof())),
202        }
203    }
204}
205
206#[derive(Copy, Clone)]
207pub struct Or<A, B> {
208    pub(super) first: A,
209    pub(super) second: B,
210}
211impl<'i, A: Parser<'i>, B: Parser<'i, Output = A::Output>> Parser<'i> for Or<A, B> {
212    type Output = A::Output;
213    type Then<T: Parser<'i>> = Then2<Self, T>;
214
215    #[inline(always)]
216    #[expect(
217        clippy::inline_always,
218        reason = "required for parsing of long or chains to be inlined"
219    )]
220    fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
221        match self.first.parse(input) {
222            Ok(v) => Ok(v),
223            Err((err1, remaining1)) => match self.second.parse(input) {
224                Ok(v) => Ok(v),
225                Err((err2, remaining2)) => {
226                    // Return error from the parser which processed further, or the first if equal
227                    Err(if remaining1.len() <= remaining2.len() {
228                        (err1, remaining1)
229                    } else {
230                        (err2, remaining2)
231                    })
232                }
233            },
234        }
235    }
236}
237
238#[derive(Copy, Clone)]
239pub struct WithConsumed<P> {
240    pub(super) parser: P,
241}
242impl<'i, P: Parser<'i>> Parser<'i> for WithConsumed<P> {
243    type Output = (P::Output, &'i [u8]);
244    type Then<T: Parser<'i>> = Then2<Self, T>;
245
246    #[inline]
247    fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
248        match self.parser.parse(input) {
249            Ok((v, remaining)) => Ok(((v, &input[..input.len() - remaining.len()]), remaining)),
250            Err(e) => Err(e),
251        }
252    }
253}
254
255#[derive(Copy, Clone)]
256pub struct WithPrefix<A, B> {
257    pub(super) parser: A,
258    pub(super) prefix: B,
259}
260impl<'i, A: Parser<'i>, B: Parser<'i>> Parser<'i> for WithPrefix<A, B> {
261    type Output = A::Output;
262    type Then<T: Parser<'i>> = Then2<Self, T>;
263
264    #[inline]
265    fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
266        match self.prefix.parse(input) {
267            Ok((_, remaining)) => self.parser.parse(remaining),
268            Err(e) => Err(e),
269        }
270    }
271}
272
273#[derive(Copy, Clone)]
274pub struct WithSuffix<A, B> {
275    pub(super) parser: A,
276    pub(super) suffix: B,
277}
278impl<'i, A: Parser<'i>, B: Parser<'i>> Parser<'i> for WithSuffix<A, B> {
279    type Output = A::Output;
280    type Then<T: Parser<'i>> = Then2<Self, T>;
281
282    #[inline]
283    fn parse(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output> {
284        match self.parser.parse(input) {
285            Ok((v, remaining1)) => match self.suffix.parse(remaining1) {
286                Ok((_, remaining2)) => Ok((v, remaining2)),
287                Err(e) => Err(e),
288            },
289            Err(e) => Err(e),
290        }
291    }
292}