use super::*;
#[derive(Copy, Clone)]
pub struct Then<O1, O2, A, B, const I: bool, const AI: bool>(
pub(crate) A,
pub(crate) B,
pub(crate) core::marker::PhantomData<(O1, O2)>,
);
impl<I: InputType, E: ParserExtras<I>, O1, O2, A: Parser<I, O1, E>, B: Parser<I, O2, E>>
Parser<I, (O1, O2), E> for Then<O1, O2, A, B, true, false>
{
fn parse<'parse>(&self, input: Input<'parse, I, E>) -> IResult<'parse, I, E, (O1, O2)> {
let (input, a) = self.0.parse(input)?;
let (input, b) = self.1.parse(input)?;
Ok((input, (a, b)))
}
fn check<'parse>(&self, input: Input<'parse, I, E>) -> IResult<'parse, I, E, ()> {
let (input, ()) = self.0.check(input)?;
let (input, ()) = self.0.check(input)?;
Ok((input, ()))
}
}
impl<I: InputType, E: ParserExtras<I>, O1, O2, A: Parser<I, O1, E>, B: Parser<I, O2, E>>
Parser<I, O1, E> for Then<O1, O2, A, B, false, false>
{
fn parse<'parse>(&self, input: Input<'parse, I, E>) -> IResult<'parse, I, E, O1> {
let (input, a) = self.0.parse(input)?;
let (input, ()) = self.1.check(input)?;
Ok((input, a))
}
fn check<'parse>(&self, input: Input<'parse, I, E>) -> IResult<'parse, I, E, ()> {
let (input, ()) = self.0.check(input)?;
let (input, ()) = self.1.check(input)?;
Ok((input, ()))
}
}
impl<I: InputType, E: ParserExtras<I>, O1, O2, A: Parser<I, O1, E>, B: Parser<I, O2, E>>
Parser<I, O2, E> for Then<O1, O2, A, B, false, true>
{
fn parse<'parse>(&self, input: Input<'parse, I, E>) -> IResult<'parse, I, E, O2> {
let (input, ()) = self.0.check(input)?;
let (input, b) = self.1.parse(input)?;
Ok((input, b))
}
fn check<'parse>(&self, input: Input<'parse, I, E>) -> IResult<'parse, I, E, ()> {
let (input, ()) = self.0.check(input)?;
let (input, ()) = self.1.check(input)?;
Ok((input, ()))
}
}
#[derive(Copy, Clone)]
pub struct Tuple<T> {
parsers: T,
}
pub const fn tuple<T>(parsers: T) -> Tuple<T> {
Tuple { parsers }
}
macro_rules! flatten_map {
(<$M:ident> $head:ident) => {
$M::map(
$head,
|$head| ($head,),
)
};
(<$M:ident> $head1:ident $head2:ident) => {
$M::combine(
$head1,
$head2,
|$head1, $head2| ($head1, $head2),
)
};
(<$M:ident> $head:ident $($X:ident)+) => {
$M::combine(
$head,
flatten_map!(
<$M>
$($X)+
),
|$head, ($($X),+)| ($head, $($X),+),
)
};
}
macro_rules! impl_tuple_for_tuple {
() => {};
($head:ident $ohead:ident $($X:ident $O:ident)*) => {
impl_tuple_for_tuple!($($X $O)*);
impl_tuple_for_tuple!(~ $head $ohead $($X $O)*);
};
(~ $($X:ident $O:ident)*) => {
#[allow(unused_variables, non_snake_case)]
impl<I, E, $($X),*, $($O),*> Parser<I, ($($O,)*), E> for Tuple<($($X,)*)>
where
I: InputType,
E: ParserExtras<I>,
$($X: Parser<I, $O, E>),*
{
#[inline]
fn parse<'parse>(&self, inp: Input<'parse, I, E>) -> IResult<'parse, I, E, ($($O,)*)> {
let Tuple { parsers: ($($X,)*) } = self;
$(
let (inp, $X) = $X.parse(inp)?;
)*
Ok((inp, flatten_map!(<Emit> $($X)*)))
}
#[inline]
fn check<'parse>(&self, inp: Input<'parse, I, E>) -> IResult<'parse, I, E, ()> {
let Tuple { parsers: ($($X,)*) } = self;
$(
let (inp, $X) = $X.parse(inp)?;
)*
Ok((inp, ()))
}
}
};
}
impl_tuple_for_tuple! {
A_ OA
B_ OB
C_ OC
D_ OD
E_ OE
F_ OF
G_ OG
H_ OH
I_ OI
J_ OJ
K_ OK
L_ OL
M_ OM
N_ ON
O_ OO
P_ OP
Q_ OQ
R_ OR
S_ OS
T_ OT
U_ OU
V_ OV
W_ OW
X_ OX
Y_ OY
Z_ OZ
}