#[cfg(test)]
mod tests;
use crate::error::ParseError;
use crate::internal::{IResult, Parser};
use crate::{Check, OutputM, OutputMode, PResult};
pub fn pair<I, O1, O2, E: ParseError<I>, F, G>(
first: F,
second: G,
) -> impl Parser<I, Output = (O1, O2), Error = E>
where
F: Parser<I, Output = O1, Error = E>,
G: Parser<I, Output = O2, Error = E>,
{
first.and(second)
}
pub fn preceded<I, O, E: ParseError<I>, F, G>(
first: F,
second: G,
) -> impl Parser<I, Output = O, Error = E>
where
F: Parser<I, Error = E>,
G: Parser<I, Output = O, Error = E>,
{
Preceded {
f: first,
g: second,
}
}
pub struct Preceded<F, G> {
f: F,
g: G,
}
impl<I, E: ParseError<I>, F: Parser<I, Error = E>, G: Parser<I, Error = E>> Parser<I>
for Preceded<F, G>
{
type Output = <G as Parser<I>>::Output;
type Error = E;
#[inline(always)]
fn process<OM: OutputMode>(&mut self, i: I) -> PResult<OM, I, Self::Output, Self::Error> {
let (i, _) = self
.f
.process::<OutputM<Check, OM::Error, OM::Incomplete>>(i)?;
let (i, o2) = self.g.process::<OM>(i)?;
Ok((i, o2))
}
}
pub fn terminated<I, O, E: ParseError<I>, F, G>(
first: F,
second: G,
) -> impl Parser<I, Output = O, Error = E>
where
F: Parser<I, Output = O, Error = E>,
G: Parser<I, Error = E>,
{
Terminated {
f: first,
g: second,
}
}
pub struct Terminated<F, G> {
f: F,
g: G,
}
impl<I, E: ParseError<I>, F: Parser<I, Error = E>, G: Parser<I, Error = E>> Parser<I>
for Terminated<F, G>
{
type Output = <F as Parser<I>>::Output;
type Error = E;
#[inline(always)]
fn process<OM: OutputMode>(&mut self, i: I) -> PResult<OM, I, Self::Output, Self::Error> {
let (i, o1) = self.f.process::<OM>(i)?;
let (i, _) = self
.g
.process::<OutputM<Check, OM::Error, OM::Incomplete>>(i)?;
Ok((i, o1))
}
}
pub fn separated_pair<I, O1, O2, E: ParseError<I>, F, G, H>(
first: F,
sep: G,
second: H,
) -> impl Parser<I, Output = (O1, O2), Error = E>
where
F: Parser<I, Output = O1, Error = E>,
G: Parser<I, Error = E>,
H: Parser<I, Output = O2, Error = E>,
{
first.and(preceded(sep, second))
}
pub fn delimited<I, O, E: ParseError<I>, F, G, H>(
first: F,
second: G,
third: H,
) -> impl Parser<I, Output = O, Error = E>
where
F: Parser<I, Error = E>,
G: Parser<I, Output = O, Error = E>,
H: Parser<I, Error = E>,
{
preceded(first, terminated(second, third))
}
#[deprecated(since = "8.0.0", note = "`Parser` is directly implemented for tuples")]
#[allow(deprecated)]
pub trait Tuple<I, O, E> {
fn parse_tuple(&mut self, input: I) -> IResult<I, O, E>;
}
#[allow(deprecated)]
impl<Input, Output, Error: ParseError<Input>, F: Parser<Input, Output = Output, Error = Error>>
Tuple<Input, (Output,), Error> for (F,)
{
fn parse_tuple(&mut self, input: Input) -> IResult<Input, (Output,), Error> {
self.0.parse(input).map(|(i, o)| (i, (o,)))
}
}
macro_rules! tuple_trait(
($name1:ident $ty1:ident, $name2: ident $ty2:ident, $($name:ident $ty:ident),*) => (
tuple_trait!(__impl $name1 $ty1, $name2 $ty2; $($name $ty),*);
);
(__impl $($name:ident $ty: ident),+; $name1:ident $ty1:ident, $($name2:ident $ty2:ident),*) => (
tuple_trait_impl!($($name $ty),+);
tuple_trait!(__impl $($name $ty),+ , $name1 $ty1; $($name2 $ty2),*);
);
(__impl $($name:ident $ty: ident),+; $name1:ident $ty1:ident) => (
tuple_trait_impl!($($name $ty),+);
tuple_trait_impl!($($name $ty),+, $name1 $ty1);
);
);
macro_rules! tuple_trait_impl(
($($name:ident $ty: ident),+) => (
#[allow(deprecated)]
impl<
Input: Clone, $($ty),+ , Error: ParseError<Input>,
$($name: Parser<Input, Output = $ty, Error = Error>),+
> Tuple<Input, ( $($ty),+ ), Error> for ( $($name),+ ) {
fn parse_tuple(&mut self, input: Input) -> IResult<Input, ( $($ty),+ ), Error> {
tuple_trait_inner!(0, self, input, (), $($name)+)
}
}
);
);
macro_rules! tuple_trait_inner(
($it:tt, $self:expr, $input:expr, (), $head:ident $($id:ident)+) => ({
let (i, o) = $self.$it.parse($input)?;
succ!($it, tuple_trait_inner!($self, i, ( o ), $($id)+))
});
($it:tt, $self:expr, $input:expr, ($($parsed:tt)*), $head:ident $($id:ident)+) => ({
let (i, o) = $self.$it.parse($input)?;
succ!($it, tuple_trait_inner!($self, i, ($($parsed)* , o), $($id)+))
});
($it:tt, $self:expr, $input:expr, ($($parsed:tt)*), $head:ident) => ({
let (i, o) = $self.$it.parse($input)?;
Ok((i, ($($parsed)* , o)))
});
);
tuple_trait!(FnA A, FnB B, FnC C, FnD D, FnE E, FnF F, FnG G, FnH H, FnI I, FnJ J, FnK K, FnL L,
FnM M, FnN N, FnO O, FnP P, FnQ Q, FnR R, FnS S, FnT T, FnU U);
#[allow(deprecated)]
impl<I, E: ParseError<I>> Tuple<I, (), E> for () {
fn parse_tuple(&mut self, input: I) -> IResult<I, (), E> {
Ok((input, ()))
}
}
#[deprecated(since = "8.0.0", note = "`Parser` is directly implemented for tuples")]
#[allow(deprecated)]
pub fn tuple<I, O, E: ParseError<I>, List: Tuple<I, O, E>>(
mut l: List,
) -> impl FnMut(I) -> IResult<I, O, E> {
move |i: I| l.parse_tuple(i)
}