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