utils/parser/
simple.rs

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