utils/parser/simple.rs
1use crate::parser::{Leaf, LeafResult, ParseError};
2use std::ops::RangeInclusive;
3
4#[derive(Copy, Clone)]
5pub struct Byte();
6impl<'i> Leaf<'i> for Byte {
7 type Output = u8;
8
9 #[inline]
10 fn parse(&self, input: &'i [u8]) -> LeafResult<'i, Self::Output> {
11 if let [byte, remaining @ ..] = input {
12 Ok((*byte, remaining))
13 } else {
14 Err((ParseError::Expected("byte"), input))
15 }
16 }
17}
18
19/// [`Leaf`] parser that consumes a single byte.
20///
21/// Not to be confused with [`u8`](super::u8), which parses a number in the range 0-255.
22///
23/// # Examples
24/// ```
25/// # use utils::parser::{self, Leaf};
26/// assert_eq!(
27/// parser::byte().parse(b"abcdef"),
28/// Ok((b'a', &b"bcdef"[..]))
29/// );
30/// assert_eq!(
31/// parser::byte().parse(b"123"),
32/// Ok((b'1', &b"23"[..]))
33/// );
34/// ```
35#[inline]
36#[must_use]
37pub fn byte() -> Byte {
38 Byte()
39}
40
41#[derive(Copy, Clone)]
42pub struct ByteLut<'a, O> {
43 lut: &'a [Option<O>; 256],
44 error: ParseError,
45}
46impl<'i, O: Copy> Leaf<'i> for ByteLut<'_, O> {
47 type Output = O;
48
49 #[inline]
50 fn parse(&self, input: &'i [u8]) -> LeafResult<'i, Self::Output> {
51 if let [byte, remaining @ ..] = input
52 && let Some(output) = self.lut[*byte as usize]
53 {
54 Ok((output, remaining))
55 } else {
56 Err((self.error, input))
57 }
58 }
59}
60
61/// [`Leaf`] parser that consumes a single byte and maps it using a lookup table.
62///
63/// Equivalent to `parser::byte().map_res(|b| LOOKUP[b as usize].ok_or("expected ..."))`, which is
64/// usually faster than an equivalent match statement in the closure.
65///
66/// See also [`parser::byte_map!`](crate::parser::byte_map!) which wraps this function, allowing a
67/// match-like syntax to be used to define the lookup table.
68///
69/// # Examples
70/// ```
71/// # use utils::parser::{self, Leaf, ParseError};
72/// const LOOKUP: [Option<bool>; 256] = {
73/// let mut x = [None; 256];
74/// x['#' as usize] = Some(true);
75/// x['.' as usize] = Some(false);
76/// x
77/// };
78///
79/// let parser = parser::byte_lut(&LOOKUP, ParseError::Custom("expected '#' or '.'"));
80/// assert_eq!(parser.parse(b"#..##"), Ok((true, &b"..##"[..])));
81/// assert_eq!(parser.parse(b"..##"), Ok((false, &b".##"[..])));
82/// assert_eq!(parser.parse(b"abc"), Err((ParseError::Custom("expected '#' or '.'"), &b"abc"[..])));
83/// ```
84#[inline]
85#[must_use]
86pub fn byte_lut<T: Copy>(lut: &'_ [Option<T>; 256], error: ParseError) -> ByteLut<'_, T> {
87 ByteLut { lut, error }
88}
89
90#[derive(Copy, Clone)]
91pub struct ByteRange {
92 min: u8,
93 max: u8,
94}
95impl<'i> Leaf<'i> for ByteRange {
96 type Output = u8;
97
98 #[inline]
99 fn parse(&self, input: &'i [u8]) -> LeafResult<'i, Self::Output> {
100 if let [byte, remaining @ ..] = input {
101 if *byte >= self.min && *byte <= self.max {
102 Ok((*byte, remaining))
103 } else {
104 Err((ParseError::ExpectedByteRange(self.min, self.max), input))
105 }
106 } else {
107 Err((ParseError::Expected("byte"), input))
108 }
109 }
110}
111
112/// [`Leaf`] parser that consumes a single byte in the supplied range.
113///
114/// See also [`number_range`](super::number_range) and [`byte`].
115///
116/// # Examples
117/// ```
118/// # use utils::parser::{self, Leaf};
119/// assert_eq!(
120/// parser::byte_range(b'a'..=b'z').parse(b"hello world"),
121/// Ok((b'h', &b"ello world"[..]))
122/// );
123/// ```
124#[inline]
125#[must_use]
126pub fn byte_range(range: RangeInclusive<u8>) -> ByteRange {
127 let min = *range.start();
128 let max = *range.end();
129 assert!(min <= max);
130 ByteRange { min, max }
131}
132
133#[derive(Copy, Clone)]
134pub struct Constant<V: Copy>(pub(super) V);
135impl<'i, V: Copy> Leaf<'i> for Constant<V> {
136 type Output = V;
137
138 #[inline]
139 fn parse(&self, input: &'i [u8]) -> LeafResult<'i, Self::Output> {
140 Ok((self.0, input))
141 }
142}
143
144/// [`Leaf`] parser that consumes no input and always succeeds, returning the provided value.
145///
146/// # Examples
147/// ```
148/// # use utils::parser::{self, Leaf};
149/// assert_eq!(
150/// parser::constant(1).parse(b"abc"),
151/// Ok((1, &b"abc"[..]))
152/// );
153/// ```
154#[inline]
155#[must_use]
156pub fn constant<T: Copy>(v: T) -> Constant<T> {
157 Constant(v)
158}
159
160/// [`Leaf`] parser that consumes no input and always succeeds, returning [`()`](unit).
161///
162/// # Examples
163/// ```
164/// # use utils::parser::{self, Leaf};
165/// assert_eq!(
166/// parser::noop().parse(b"abc"),
167/// Ok(((), &b"abc"[..]))
168/// );
169/// ```
170#[inline]
171#[must_use]
172pub fn noop() -> Constant<()> {
173 const {
174 assert!(size_of::<Constant<()>>() == 0);
175 }
176 Constant(())
177}
178
179#[derive(Copy, Clone)]
180pub struct Eof();
181impl<'i> Leaf<'i> for Eof {
182 type Output = ();
183
184 #[inline]
185 fn parse(&self, input: &'i [u8]) -> LeafResult<'i, Self::Output> {
186 match input {
187 [] => Ok(((), input)),
188 _ => Err((ParseError::ExpectedEof(), input)),
189 }
190 }
191}
192
193/// [`Leaf`] parser which matches the end of the input.
194///
195/// Useful when parsing a list and each item is separated by a separator, unless it is at the end of
196/// the input.
197///
198/// # Examples
199/// ```
200/// # use utils::parser::{self, Leaf, Parser};
201/// assert_eq!(
202/// parser::eof().parse(b""),
203/// Ok(((), &b""[..]))
204/// );
205/// assert_eq!(
206/// parser::u32()
207/// .with_suffix(b','.or(parser::eof()))
208/// .parse_all("12,34,56")
209/// .unwrap(),
210/// vec![12, 34, 56],
211/// );
212/// ```
213#[inline]
214#[must_use]
215pub fn eof() -> Eof {
216 Eof()
217}
218
219#[derive(Copy, Clone)]
220pub struct Eol();
221impl<'i> Leaf<'i> for Eol {
222 type Output = ();
223
224 #[inline]
225 fn parse(&self, input: &'i [u8]) -> LeafResult<'i, Self::Output> {
226 match input {
227 [b'\n', remaining @ ..] | [b'\r', b'\n', remaining @ ..] => Ok(((), remaining)),
228 [] => Ok(((), input)),
229 _ => Err((ParseError::Expected("newline or end of input"), input)),
230 }
231 }
232}
233
234/// [`Leaf`] parser which matches newlines or the end of the input.
235///
236/// Matches both LF and CRLF line endings.
237///
238/// # Examples
239/// ```
240/// # use utils::parser::{self, Leaf};
241/// assert_eq!(
242/// parser::eol().parse(b"\nabc"),
243/// Ok(((), &b"abc"[..]))
244/// );
245/// assert_eq!(
246/// parser::eol().parse(b"\r\nabc"),
247/// Ok(((), &b"abc"[..]))
248/// );
249/// assert_eq!(
250/// parser::eol().parse(b""),
251/// Ok(((), &b""[..]))
252/// );
253/// ```
254#[inline]
255#[must_use]
256pub fn eol() -> Eol {
257 Eol()
258}
259
260#[derive(Copy, Clone)]
261pub struct TakeWhile<const N: usize>(fn(&u8) -> bool);
262impl<'i, const N: usize> Leaf<'i> for TakeWhile<N> {
263 type Output = &'i [u8];
264
265 #[inline]
266 fn parse(&self, input: &'i [u8]) -> LeafResult<'i, Self::Output> {
267 let mut end = 0;
268 while end < input.len() && self.0(&input[end]) {
269 end += 1;
270 }
271 if end >= N {
272 Ok(input.split_at(end))
273 } else {
274 Err((ParseError::ExpectedMatches(N), &input[end..]))
275 }
276 }
277}
278
279/// [`Leaf`] parser for substrings matching the provided function.
280///
281/// # Examples
282/// ```
283/// # use utils::parser::{self, Leaf};
284/// let parser = parser::take_while(u8::is_ascii_lowercase);
285/// assert_eq!(
286/// parser.parse(b"abc def"),
287/// Ok((&b"abc"[..], &b" def"[..]))
288/// );
289/// assert_eq!(
290/// parser.parse(b"ABC"),
291/// Ok((&b""[..], &b"ABC"[..]))
292/// );
293/// ```
294#[inline]
295#[must_use]
296pub fn take_while(f: fn(&u8) -> bool) -> TakeWhile<0> {
297 TakeWhile(f)
298}
299
300/// [`Leaf`] parser for non-empty substrings matching the provided function.
301///
302/// # Examples
303/// ```
304/// # use utils::parser::{self, Leaf};
305/// let parser = parser::take_while1(u8::is_ascii_lowercase);
306/// assert_eq!(
307/// parser.parse(b"abc def"),
308/// Ok((&b"abc"[..], &b" def"[..]))
309/// );
310/// assert!(parser.parse(b"ABC").is_err());
311/// ```
312#[inline]
313#[must_use]
314pub fn take_while1(f: fn(&u8) -> bool) -> TakeWhile<1> {
315 TakeWhile(f)
316}