16855e09eSopenharmony_ci//! Combinators applying parsers in sequence
26855e09eSopenharmony_ci
36855e09eSopenharmony_ci#[cfg(test)]
46855e09eSopenharmony_cimod tests;
56855e09eSopenharmony_ci
66855e09eSopenharmony_ciuse crate::error::ParseError;
76855e09eSopenharmony_ciuse crate::internal::{IResult, Parser};
86855e09eSopenharmony_ci
96855e09eSopenharmony_ci/// Gets an object from the first parser,
106855e09eSopenharmony_ci/// then gets another object from the second parser.
116855e09eSopenharmony_ci///
126855e09eSopenharmony_ci/// # Arguments
136855e09eSopenharmony_ci/// * `first` The first parser to apply.
146855e09eSopenharmony_ci/// * `second` The second parser to apply.
156855e09eSopenharmony_ci///
166855e09eSopenharmony_ci/// ```rust
176855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed};
186855e09eSopenharmony_ci/// # use nom::Needed::Size;
196855e09eSopenharmony_ci/// use nom::sequence::pair;
206855e09eSopenharmony_ci/// use nom::bytes::complete::tag;
216855e09eSopenharmony_ci///
226855e09eSopenharmony_ci/// let mut parser = pair(tag("abc"), tag("efg"));
236855e09eSopenharmony_ci///
246855e09eSopenharmony_ci/// assert_eq!(parser("abcefg"), Ok(("", ("abc", "efg"))));
256855e09eSopenharmony_ci/// assert_eq!(parser("abcefghij"), Ok(("hij", ("abc", "efg"))));
266855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
276855e09eSopenharmony_ci/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
286855e09eSopenharmony_ci/// ```
296855e09eSopenharmony_cipub fn pair<I, O1, O2, E: ParseError<I>, F, G>(
306855e09eSopenharmony_ci  mut first: F,
316855e09eSopenharmony_ci  mut second: G,
326855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, (O1, O2), E>
336855e09eSopenharmony_ciwhere
346855e09eSopenharmony_ci  F: Parser<I, O1, E>,
356855e09eSopenharmony_ci  G: Parser<I, O2, E>,
366855e09eSopenharmony_ci{
376855e09eSopenharmony_ci  move |input: I| {
386855e09eSopenharmony_ci    let (input, o1) = first.parse(input)?;
396855e09eSopenharmony_ci    second.parse(input).map(|(i, o2)| (i, (o1, o2)))
406855e09eSopenharmony_ci  }
416855e09eSopenharmony_ci}
426855e09eSopenharmony_ci
436855e09eSopenharmony_ci/// Matches an object from the first parser and discards it,
446855e09eSopenharmony_ci/// then gets an object from the second parser.
456855e09eSopenharmony_ci///
466855e09eSopenharmony_ci/// # Arguments
476855e09eSopenharmony_ci/// * `first` The opening parser.
486855e09eSopenharmony_ci/// * `second` The second parser to get object.
496855e09eSopenharmony_ci///
506855e09eSopenharmony_ci/// ```rust
516855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed};
526855e09eSopenharmony_ci/// # use nom::Needed::Size;
536855e09eSopenharmony_ci/// use nom::sequence::preceded;
546855e09eSopenharmony_ci/// use nom::bytes::complete::tag;
556855e09eSopenharmony_ci///
566855e09eSopenharmony_ci/// let mut parser = preceded(tag("abc"), tag("efg"));
576855e09eSopenharmony_ci///
586855e09eSopenharmony_ci/// assert_eq!(parser("abcefg"), Ok(("", "efg")));
596855e09eSopenharmony_ci/// assert_eq!(parser("abcefghij"), Ok(("hij", "efg")));
606855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
616855e09eSopenharmony_ci/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
626855e09eSopenharmony_ci/// ```
636855e09eSopenharmony_cipub fn preceded<I, O1, O2, E: ParseError<I>, F, G>(
646855e09eSopenharmony_ci  mut first: F,
656855e09eSopenharmony_ci  mut second: G,
666855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, O2, E>
676855e09eSopenharmony_ciwhere
686855e09eSopenharmony_ci  F: Parser<I, O1, E>,
696855e09eSopenharmony_ci  G: Parser<I, O2, E>,
706855e09eSopenharmony_ci{
716855e09eSopenharmony_ci  move |input: I| {
726855e09eSopenharmony_ci    let (input, _) = first.parse(input)?;
736855e09eSopenharmony_ci    second.parse(input)
746855e09eSopenharmony_ci  }
756855e09eSopenharmony_ci}
766855e09eSopenharmony_ci
776855e09eSopenharmony_ci/// Gets an object from the first parser,
786855e09eSopenharmony_ci/// then matches an object from the second parser and discards it.
796855e09eSopenharmony_ci///
806855e09eSopenharmony_ci/// # Arguments
816855e09eSopenharmony_ci/// * `first` The first parser to apply.
826855e09eSopenharmony_ci/// * `second` The second parser to match an object.
836855e09eSopenharmony_ci///
846855e09eSopenharmony_ci/// ```rust
856855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed};
866855e09eSopenharmony_ci/// # use nom::Needed::Size;
876855e09eSopenharmony_ci/// use nom::sequence::terminated;
886855e09eSopenharmony_ci/// use nom::bytes::complete::tag;
896855e09eSopenharmony_ci///
906855e09eSopenharmony_ci/// let mut parser = terminated(tag("abc"), tag("efg"));
916855e09eSopenharmony_ci///
926855e09eSopenharmony_ci/// assert_eq!(parser("abcefg"), Ok(("", "abc")));
936855e09eSopenharmony_ci/// assert_eq!(parser("abcefghij"), Ok(("hij", "abc")));
946855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
956855e09eSopenharmony_ci/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
966855e09eSopenharmony_ci/// ```
976855e09eSopenharmony_cipub fn terminated<I, O1, O2, E: ParseError<I>, F, G>(
986855e09eSopenharmony_ci  mut first: F,
996855e09eSopenharmony_ci  mut second: G,
1006855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, O1, E>
1016855e09eSopenharmony_ciwhere
1026855e09eSopenharmony_ci  F: Parser<I, O1, E>,
1036855e09eSopenharmony_ci  G: Parser<I, O2, E>,
1046855e09eSopenharmony_ci{
1056855e09eSopenharmony_ci  move |input: I| {
1066855e09eSopenharmony_ci    let (input, o1) = first.parse(input)?;
1076855e09eSopenharmony_ci    second.parse(input).map(|(i, _)| (i, o1))
1086855e09eSopenharmony_ci  }
1096855e09eSopenharmony_ci}
1106855e09eSopenharmony_ci
1116855e09eSopenharmony_ci/// Gets an object from the first parser,
1126855e09eSopenharmony_ci/// then matches an object from the sep_parser and discards it,
1136855e09eSopenharmony_ci/// then gets another object from the second parser.
1146855e09eSopenharmony_ci///
1156855e09eSopenharmony_ci/// # Arguments
1166855e09eSopenharmony_ci/// * `first` The first parser to apply.
1176855e09eSopenharmony_ci/// * `sep` The separator parser to apply.
1186855e09eSopenharmony_ci/// * `second` The second parser to apply.
1196855e09eSopenharmony_ci///
1206855e09eSopenharmony_ci/// ```rust
1216855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed};
1226855e09eSopenharmony_ci/// # use nom::Needed::Size;
1236855e09eSopenharmony_ci/// use nom::sequence::separated_pair;
1246855e09eSopenharmony_ci/// use nom::bytes::complete::tag;
1256855e09eSopenharmony_ci///
1266855e09eSopenharmony_ci/// let mut parser = separated_pair(tag("abc"), tag("|"), tag("efg"));
1276855e09eSopenharmony_ci///
1286855e09eSopenharmony_ci/// assert_eq!(parser("abc|efg"), Ok(("", ("abc", "efg"))));
1296855e09eSopenharmony_ci/// assert_eq!(parser("abc|efghij"), Ok(("hij", ("abc", "efg"))));
1306855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
1316855e09eSopenharmony_ci/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
1326855e09eSopenharmony_ci/// ```
1336855e09eSopenharmony_cipub fn separated_pair<I, O1, O2, O3, E: ParseError<I>, F, G, H>(
1346855e09eSopenharmony_ci  mut first: F,
1356855e09eSopenharmony_ci  mut sep: G,
1366855e09eSopenharmony_ci  mut second: H,
1376855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, (O1, O3), E>
1386855e09eSopenharmony_ciwhere
1396855e09eSopenharmony_ci  F: Parser<I, O1, E>,
1406855e09eSopenharmony_ci  G: Parser<I, O2, E>,
1416855e09eSopenharmony_ci  H: Parser<I, O3, E>,
1426855e09eSopenharmony_ci{
1436855e09eSopenharmony_ci  move |input: I| {
1446855e09eSopenharmony_ci    let (input, o1) = first.parse(input)?;
1456855e09eSopenharmony_ci    let (input, _) = sep.parse(input)?;
1466855e09eSopenharmony_ci    second.parse(input).map(|(i, o2)| (i, (o1, o2)))
1476855e09eSopenharmony_ci  }
1486855e09eSopenharmony_ci}
1496855e09eSopenharmony_ci
1506855e09eSopenharmony_ci/// Matches an object from the first parser and discards it,
1516855e09eSopenharmony_ci/// then gets an object from the second parser,
1526855e09eSopenharmony_ci/// and finally matches an object from the third parser and discards it.
1536855e09eSopenharmony_ci///
1546855e09eSopenharmony_ci/// # Arguments
1556855e09eSopenharmony_ci/// * `first` The first parser to apply and discard.
1566855e09eSopenharmony_ci/// * `second` The second parser to apply.
1576855e09eSopenharmony_ci/// * `third` The third parser to apply and discard.
1586855e09eSopenharmony_ci///
1596855e09eSopenharmony_ci/// ```rust
1606855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind, Needed};
1616855e09eSopenharmony_ci/// # use nom::Needed::Size;
1626855e09eSopenharmony_ci/// use nom::sequence::delimited;
1636855e09eSopenharmony_ci/// use nom::bytes::complete::tag;
1646855e09eSopenharmony_ci///
1656855e09eSopenharmony_ci/// let mut parser = delimited(tag("("), tag("abc"), tag(")"));
1666855e09eSopenharmony_ci///
1676855e09eSopenharmony_ci/// assert_eq!(parser("(abc)"), Ok(("", "abc")));
1686855e09eSopenharmony_ci/// assert_eq!(parser("(abc)def"), Ok(("def", "abc")));
1696855e09eSopenharmony_ci/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
1706855e09eSopenharmony_ci/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
1716855e09eSopenharmony_ci/// ```
1726855e09eSopenharmony_cipub fn delimited<I, O1, O2, O3, E: ParseError<I>, F, G, H>(
1736855e09eSopenharmony_ci  mut first: F,
1746855e09eSopenharmony_ci  mut second: G,
1756855e09eSopenharmony_ci  mut third: H,
1766855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, O2, E>
1776855e09eSopenharmony_ciwhere
1786855e09eSopenharmony_ci  F: Parser<I, O1, E>,
1796855e09eSopenharmony_ci  G: Parser<I, O2, E>,
1806855e09eSopenharmony_ci  H: Parser<I, O3, E>,
1816855e09eSopenharmony_ci{
1826855e09eSopenharmony_ci  move |input: I| {
1836855e09eSopenharmony_ci    let (input, _) = first.parse(input)?;
1846855e09eSopenharmony_ci    let (input, o2) = second.parse(input)?;
1856855e09eSopenharmony_ci    third.parse(input).map(|(i, _)| (i, o2))
1866855e09eSopenharmony_ci  }
1876855e09eSopenharmony_ci}
1886855e09eSopenharmony_ci
1896855e09eSopenharmony_ci/// Helper trait for the tuple combinator.
1906855e09eSopenharmony_ci///
1916855e09eSopenharmony_ci/// This trait is implemented for tuples of parsers of up to 21 elements.
1926855e09eSopenharmony_cipub trait Tuple<I, O, E> {
1936855e09eSopenharmony_ci  /// Parses the input and returns a tuple of results of each parser.
1946855e09eSopenharmony_ci  fn parse(&mut self, input: I) -> IResult<I, O, E>;
1956855e09eSopenharmony_ci}
1966855e09eSopenharmony_ci
1976855e09eSopenharmony_ciimpl<Input, Output, Error: ParseError<Input>, F: Parser<Input, Output, Error>>
1986855e09eSopenharmony_ci  Tuple<Input, (Output,), Error> for (F,)
1996855e09eSopenharmony_ci{
2006855e09eSopenharmony_ci  fn parse(&mut self, input: Input) -> IResult<Input, (Output,), Error> {
2016855e09eSopenharmony_ci    self.0.parse(input).map(|(i, o)| (i, (o,)))
2026855e09eSopenharmony_ci  }
2036855e09eSopenharmony_ci}
2046855e09eSopenharmony_ci
2056855e09eSopenharmony_cimacro_rules! tuple_trait(
2066855e09eSopenharmony_ci  ($name1:ident $ty1:ident, $name2: ident $ty2:ident, $($name:ident $ty:ident),*) => (
2076855e09eSopenharmony_ci    tuple_trait!(__impl $name1 $ty1, $name2 $ty2; $($name $ty),*);
2086855e09eSopenharmony_ci  );
2096855e09eSopenharmony_ci  (__impl $($name:ident $ty: ident),+; $name1:ident $ty1:ident, $($name2:ident $ty2:ident),*) => (
2106855e09eSopenharmony_ci    tuple_trait_impl!($($name $ty),+);
2116855e09eSopenharmony_ci    tuple_trait!(__impl $($name $ty),+ , $name1 $ty1; $($name2 $ty2),*);
2126855e09eSopenharmony_ci  );
2136855e09eSopenharmony_ci  (__impl $($name:ident $ty: ident),+; $name1:ident $ty1:ident) => (
2146855e09eSopenharmony_ci    tuple_trait_impl!($($name $ty),+);
2156855e09eSopenharmony_ci    tuple_trait_impl!($($name $ty),+, $name1 $ty1);
2166855e09eSopenharmony_ci  );
2176855e09eSopenharmony_ci);
2186855e09eSopenharmony_ci
2196855e09eSopenharmony_cimacro_rules! tuple_trait_impl(
2206855e09eSopenharmony_ci  ($($name:ident $ty: ident),+) => (
2216855e09eSopenharmony_ci    impl<
2226855e09eSopenharmony_ci      Input: Clone, $($ty),+ , Error: ParseError<Input>,
2236855e09eSopenharmony_ci      $($name: Parser<Input, $ty, Error>),+
2246855e09eSopenharmony_ci    > Tuple<Input, ( $($ty),+ ), Error> for ( $($name),+ ) {
2256855e09eSopenharmony_ci
2266855e09eSopenharmony_ci      fn parse(&mut self, input: Input) -> IResult<Input, ( $($ty),+ ), Error> {
2276855e09eSopenharmony_ci        tuple_trait_inner!(0, self, input, (), $($name)+)
2286855e09eSopenharmony_ci
2296855e09eSopenharmony_ci      }
2306855e09eSopenharmony_ci    }
2316855e09eSopenharmony_ci  );
2326855e09eSopenharmony_ci);
2336855e09eSopenharmony_ci
2346855e09eSopenharmony_cimacro_rules! tuple_trait_inner(
2356855e09eSopenharmony_ci  ($it:tt, $self:expr, $input:expr, (), $head:ident $($id:ident)+) => ({
2366855e09eSopenharmony_ci    let (i, o) = $self.$it.parse($input.clone())?;
2376855e09eSopenharmony_ci
2386855e09eSopenharmony_ci    succ!($it, tuple_trait_inner!($self, i, ( o ), $($id)+))
2396855e09eSopenharmony_ci  });
2406855e09eSopenharmony_ci  ($it:tt, $self:expr, $input:expr, ($($parsed:tt)*), $head:ident $($id:ident)+) => ({
2416855e09eSopenharmony_ci    let (i, o) = $self.$it.parse($input.clone())?;
2426855e09eSopenharmony_ci
2436855e09eSopenharmony_ci    succ!($it, tuple_trait_inner!($self, i, ($($parsed)* , o), $($id)+))
2446855e09eSopenharmony_ci  });
2456855e09eSopenharmony_ci  ($it:tt, $self:expr, $input:expr, ($($parsed:tt)*), $head:ident) => ({
2466855e09eSopenharmony_ci    let (i, o) = $self.$it.parse($input.clone())?;
2476855e09eSopenharmony_ci
2486855e09eSopenharmony_ci    Ok((i, ($($parsed)* , o)))
2496855e09eSopenharmony_ci  });
2506855e09eSopenharmony_ci);
2516855e09eSopenharmony_ci
2526855e09eSopenharmony_cituple_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,
2536855e09eSopenharmony_ci  FnM M, FnN N, FnO O, FnP P, FnQ Q, FnR R, FnS S, FnT T, FnU U);
2546855e09eSopenharmony_ci
2556855e09eSopenharmony_ci// Special case: implement `Tuple` for `()`, the unit type.
2566855e09eSopenharmony_ci// This can come up in macros which accept a variable number of arguments.
2576855e09eSopenharmony_ci// Literally, `()` is an empty tuple, so it should simply parse nothing.
2586855e09eSopenharmony_ciimpl<I, E: ParseError<I>> Tuple<I, (), E> for () {
2596855e09eSopenharmony_ci  fn parse(&mut self, input: I) -> IResult<I, (), E> {
2606855e09eSopenharmony_ci    Ok((input, ()))
2616855e09eSopenharmony_ci  }
2626855e09eSopenharmony_ci}
2636855e09eSopenharmony_ci
2646855e09eSopenharmony_ci///Applies a tuple of parsers one by one and returns their results as a tuple.
2656855e09eSopenharmony_ci///There is a maximum of 21 parsers
2666855e09eSopenharmony_ci/// ```rust
2676855e09eSopenharmony_ci/// # use nom::{Err, error::ErrorKind};
2686855e09eSopenharmony_ci/// use nom::sequence::tuple;
2696855e09eSopenharmony_ci/// use nom::character::complete::{alpha1, digit1};
2706855e09eSopenharmony_ci/// let mut parser = tuple((alpha1, digit1, alpha1));
2716855e09eSopenharmony_ci///
2726855e09eSopenharmony_ci/// assert_eq!(parser("abc123def"), Ok(("", ("abc", "123", "def"))));
2736855e09eSopenharmony_ci/// assert_eq!(parser("123def"), Err(Err::Error(("123def", ErrorKind::Alpha))));
2746855e09eSopenharmony_ci/// ```
2756855e09eSopenharmony_cipub fn tuple<I, O, E: ParseError<I>, List: Tuple<I, O, E>>(
2766855e09eSopenharmony_ci  mut l: List,
2776855e09eSopenharmony_ci) -> impl FnMut(I) -> IResult<I, O, E> {
2786855e09eSopenharmony_ci  move |i: I| l.parse(i)
2796855e09eSopenharmony_ci}
280