use super::*;
#[derive(Copy, Clone)]
pub struct Choice<T> {
parsers: T,
}
pub const fn choice<T>(parsers: T) -> Choice<T> {
Choice { parsers }
}
macro_rules! impl_choice_for_tuple {
() => {};
($head:ident $($X:ident)*) => {
impl_choice_for_tuple!($($X)*);
impl_choice_for_tuple!(~ $head $($X)*);
};
(~ $Head:ident $($X:ident)+) => {
#[allow(unused_variables, non_snake_case, unused_assignments)]
impl<I, E, $Head, $($X),*, O> Parser<I, O, E> for Choice<($Head, $($X,)*)>
where
I: InputType,
E: ParserExtras<I>,
$Head: Parser<I, O, E>,
$($X: Parser<I, O, E>),*
{
#[inline]
fn parse<'parse>(&self, mut inp: Input<'parse, I, E>) -> IResult<'parse, I, E, O> {
let mut error: E::Error;
let before = inp.save();
let Choice { parsers: ($Head, $($X,)*), .. } = self;
match $Head.parse(inp) {
Ok((inp, out)) => return Ok((inp, out)),
Err((input, e)) => { inp = input; inp.rewind(before); error = e; },
}
$(
match $X.parse(inp) {
Ok((inp, out)) => return Ok((inp, out)),
Err((input, e)) => { inp = input; inp.rewind(before); error = e; },
}
)*
Err((inp, error))
}
#[inline]
fn check<'parse>(&self, mut inp: Input<'parse, I, E>) -> IResult<'parse, I, E, ()> {
let mut error: E::Error;
let before = inp.save();
let Choice { parsers: ($Head, $($X,)*), .. } = self;
match $Head.check(inp) {
Ok((inp, out)) => return Ok((inp, out)),
Err((input, e)) => { inp = input; inp.rewind(before); error = e; },
}
$(
match $X.check(inp) {
Ok((inp, out)) => return Ok((inp, out)),
Err((input, e)) => { inp = input; inp.rewind(before); error = e; },
}
)*
Err((inp, error))
}
}
};
(~ $Head:ident) => {
impl<I, E, $Head, O> Parser<I, O, E> for Choice<($Head,)>
where
I: InputType,
E: ParserExtras<I>,
$Head: Parser<I, O, E>,
{
#[inline]
fn parse<'parse>(&self, inp: Input<'parse, I, E>) -> IResult<'parse, I, E, O> {
self.parsers.0.parse(inp)
}
#[inline]
fn check<'parse>(&self, inp: Input<'parse, I, E>) -> IResult<'parse, I, E, ()> {
self.parsers.0.check(inp)
}
}
};
}
impl_choice_for_tuple!(A_ B_ C_ D_ E_ F_ G_ H_ I_ J_ K_ L_ M_ N_ O_ P_ Q_ R_ S_ T_ U_ V_ W_ X_ Y_ Z_);