utils/parser/
then.rs

1#![allow(non_snake_case)]
2
3use crate::parser::{ParseState, Parser, ParserResult};
4
5pub trait Then<'i, P: Parser<'i>, T: Parser<'i>>: Parser<'i> {
6    fn then(parser: P, then: T) -> Self;
7}
8
9#[derive(Copy, Clone)]
10pub enum Unimplemented {}
11impl<'i> Parser<'i> for Unimplemented {
12    type Output = Unimplemented;
13    type Then<T: Parser<'i>> = Unimplemented;
14
15    fn parse_ctx(
16        &self,
17        _: &'i [u8],
18        _: &mut ParseState<'i>,
19        _: &mut bool,
20        _: bool,
21    ) -> ParserResult<'i, Self::Output> {
22        unimplemented!();
23    }
24}
25impl<'i, P: Parser<'i>, T: Parser<'i>> Then<'i, P, T> for Unimplemented {
26    fn then(_: P, _: T) -> Self {
27        unimplemented!();
28    }
29}
30
31macro_rules! then_impl {
32    (
33        $name:ident<$new:ident> => [$($t:ident),+],
34        $next_name:ident<$next_t:ident> => $($tail:tt)*
35    ) => {
36        #[derive(Copy, Clone)]
37        pub struct $name<$($t),+>{
38            $($t: $t,)+
39        }
40        impl<'i, $($t: Parser<'i>),+> Parser<'i> for $name<$($t),+> {
41            type Output = ($($t::Output),+);
42            type Then<T: Parser<'i>> = $next_name<$($t),+, T>;
43
44            #[inline(always)]
45            #[expect(unused_variables)]
46            fn parse_ctx(
47                &self,
48                input: &'i [u8],
49                state: &mut ParseState<'i>,
50                commit: &mut bool,
51                tail: bool,
52            ) -> ParserResult<'i, Self::Output> {
53                // Create variables set to false for each $t, then shadow $new to tail to pass it
54                // through to the final parser. Then, as each parser is called, shadow the variables
55                // again with the output.
56                $(let $t = false;)+
57                let $new = tail;
58                $(let ($t, input) = self.$t.parse_ctx(input, state, commit, $t)?;)+
59                Ok((($($t),+), input))
60            }
61        }
62        impl<'i, $($t: Parser<'i>),+, T: Parser<'i>> Then<'i, $name<$($t),+>, T> for $next_name<$($t),+, T> {
63            fn then(parser: $name<$($t),+>, next: T) -> Self {
64                Self{$($t: parser.$t),+, $next_t: next}
65            }
66        }
67        then_impl!{$next_name<$next_t> => $($tail)*}
68    };
69    (
70        $name:ident<$new:ident> => [$($t:ident),+],
71    ) => {
72        #[derive(Copy, Clone)]
73        pub struct $name<$($t),+>{
74            $($t: $t,)+
75        }
76        impl<'i, $($t: Parser<'i>),+> Parser<'i> for $name<$($t),+> {
77            type Output = ($($t::Output),+);
78            type Then<T: Parser<'i>> = Unimplemented;
79
80            #[inline(always)]
81            #[expect(unused_variables)]
82            fn parse_ctx(
83                &self,
84                input: &'i [u8],
85                state: &mut ParseState<'i>,
86                commit: &mut bool,
87                tail: bool,
88            ) -> ParserResult<'i, Self::Output> {
89                $(let $t = false;)+
90                let $new = tail;
91                $(let ($t, input) = self.$t.parse_ctx(input, state, commit, $t)?;)+
92                Ok((($($t),+), input))
93            }
94        }
95    };
96}
97
98then_impl! {
99    Then2<B> => [A, B],
100    Then3<C> => [A, B, C],
101    Then4<D> => [A, B, C, D],
102    Then5<E> => [A, B, C, D, E],
103    Then6<F> => [A, B, C, D, E, F],
104    Then7<G> => [A, B, C, D, E, F, G],
105    Then8<H> => [A, B, C, D, E, F, G, H],
106}
107
108impl<'i, A: Parser<'i>, B: Parser<'i>> Then<'i, A, B> for Then2<A, B> {
109    fn then(parser: A, then: B) -> Self {
110        Then2 { A: parser, B: then }
111    }
112}