utils/parser/
leaf.rs

1use crate::parser::then::Then2;
2use crate::parser::{ParseError, ParseState, Parser, ParserResult};
3
4/// [`Result`] type returned by [`Leaf::parse`].
5///
6/// Contains the error information inline, unlike [`ParserResult`].
7pub type LeafResult<'i, T> = Result<(T, &'i [u8]), (ParseError, &'i [u8])>;
8
9/// Trait implemented by atomic, fail‑fast parsers.
10///
11/// Leaf parsers always return the first error they encounter without backtracking.
12#[must_use]
13pub trait Leaf<'i>: Sized {
14    /// Type of the value produced by [`parse`](Self::parse) when successful.
15    type Output;
16
17    /// Parse one item, returning immediately on error without backtracking.
18    ///
19    /// Returns a tuple of the successfully parsed [`Output`](Self::Output) value and the
20    /// remaining bytes, or a tuple containing a [`ParseError`] and the location of the error.
21    fn parse(&self, input: &'i [u8]) -> LeafResult<'i, Self::Output>;
22}
23
24impl<'i, L: Leaf<'i>> Parser<'i> for L {
25    type Output = L::Output;
26    type Then<T: Parser<'i>> = Then2<Self, T>;
27
28    fn parse_ctx(
29        &self,
30        input: &'i [u8],
31        state: &mut ParseState<'i>,
32        _: &mut bool,
33        _: bool,
34    ) -> ParserResult<'i, Self::Output> {
35        match self.parse(input) {
36            Ok(v) => Ok(v),
37            Err((err, remaining)) => Err(state.error(err, remaining)),
38        }
39    }
40}
41
42/// Matches the string literal exactly.
43///
44/// Normally used with [`with_prefix`](Parser::with_prefix) or [`with_suffix`](Parser::with_suffix).
45impl<'i> Leaf<'i> for &'static str {
46    type Output = ();
47
48    #[inline]
49    fn parse(&self, input: &'i [u8]) -> LeafResult<'i, Self::Output> {
50        // This is faster than using strip_prefix for the common case where the string is a short
51        // string literal known at compile time.
52        if input.len() >= self.len() && self.bytes().zip(input).all(|(a, &b)| a == b) {
53            Ok(((), &input[self.len()..]))
54        } else {
55            Err((ParseError::ExpectedLiteral(self), input))
56        }
57    }
58}
59
60/// Matches the byte exactly.
61///
62/// Normally used with [`with_prefix`](Parser::with_prefix) or [`with_suffix`](Parser::with_suffix).
63impl<'i> Leaf<'i> for u8 {
64    type Output = ();
65
66    #[inline]
67    fn parse(&self, input: &'i [u8]) -> LeafResult<'i, Self::Output> {
68        if input.first() == Some(self) {
69            Ok(((), &input[1..]))
70        } else {
71            Err((ParseError::ExpectedByte(*self), input))
72        }
73    }
74}
75
76/// Allow custom functions/closures to be used as [`Leaf`] parsers.
77impl<'i, F: Fn(&'i [u8]) -> LeafResult<'i, O>, O> Leaf<'i> for F {
78    type Output = O;
79
80    #[inline]
81    fn parse(&self, input: &'i [u8]) -> LeafResult<'i, Self::Output> {
82        self(input)
83    }
84}
85
86/// Coerces the provided function/closure into a [`Leaf`] parser.
87///
88/// This function exists to help with type inference.
89#[inline]
90#[must_use]
91pub const fn from_leaf_fn<'i, F, O>(f: F) -> F
92where
93    F: Fn(&'i [u8]) -> LeafResult<'i, O>,
94    F: Leaf<'i, Output = O>,
95{
96    f
97}
98
99/// Trait for types that have a canonical [`Leaf`] parser.
100pub trait Parseable {
101    type Parser: for<'i> Leaf<'i, Output = Self>;
102    const PARSER: Self::Parser;
103}