//! combinators applying parsers in sequence #[macro_use] mod macros; use crate::internal::IResult; use crate::error::ParseError; /// Gets an object from the first parser, /// then gets another object from the second parser. /// /// # Arguments /// * `first` The first parser to apply. /// * `second` The second parser to apply. /// ```rust /// # use nom::{Err, error::ErrorKind, Needed}; /// # use nom::Needed::Size; /// use nom::sequence::pair; /// use nom::bytes::complete::tag; /// /// let parser = pair(tag("abc"), tag("efg")); /// /// assert_eq!(parser("abcefg"), Ok(("", ("abc", "efg")))); /// assert_eq!(parser("abcefghij"), Ok(("hij", ("abc", "efg")))); /// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag)))); /// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag)))); /// ``` pub fn pair, F, G>(first: F, second: G) -> impl Fn(I) -> IResult where F: Fn(I) -> IResult, G: Fn(I) -> IResult, { move |input: I| { let (input, o1) = first(input)?; second(input).map(|(i, o2)| (i, (o1, o2))) } } // this implementation is used for type inference issues in macros #[doc(hidden)] pub fn pairc, F, G>(input: I, first: F, second: G) -> IResult where F: Fn(I) -> IResult, G: Fn(I) -> IResult, { pair(first, second)(input) } /// Matches an object from the first parser and discards it, /// then gets an object from the second parser. /// /// # Arguments /// * `first` The opening parser. /// * `second` The second parser to get object. /// ```rust /// # use nom::{Err, error::ErrorKind, Needed}; /// # use nom::Needed::Size; /// use nom::sequence::preceded; /// use nom::bytes::complete::tag; /// /// let parser = preceded(tag("abc"), tag("efg")); /// /// assert_eq!(parser("abcefg"), Ok(("", "efg"))); /// assert_eq!(parser("abcefghij"), Ok(("hij", "efg"))); /// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag)))); /// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag)))); /// ``` pub fn preceded, F, G>(first: F, second: G) -> impl Fn(I) -> IResult where F: Fn(I) -> IResult, G: Fn(I) -> IResult, { move |input: I| { let (input, _) = first(input)?; second(input) } } // this implementation is used for type inference issues in macros #[doc(hidden)] pub fn precededc, F, G>(input: I, first: F, second: G) -> IResult where F: Fn(I) -> IResult, G: Fn(I) -> IResult, { preceded(first, second)(input) } /// Gets an object from the first parser, /// then matches an object from the second parser and discards it. /// /// # Arguments /// * `first` The first parser to apply. /// * `second` The second parser to match an object. /// ```rust /// # use nom::{Err, error::ErrorKind, Needed}; /// # use nom::Needed::Size; /// use nom::sequence::terminated; /// use nom::bytes::complete::tag; /// /// let parser = terminated(tag("abc"), tag("efg")); /// /// assert_eq!(parser("abcefg"), Ok(("", "abc"))); /// assert_eq!(parser("abcefghij"), Ok(("hij", "abc"))); /// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag)))); /// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag)))); /// ``` pub fn terminated, F, G>(first: F, second: G) -> impl Fn(I) -> IResult where F: Fn(I) -> IResult, G: Fn(I) -> IResult, { move |input: I| { let (input, o1) = first(input)?; second(input).map(|(i, _)| (i, o1)) } } // this implementation is used for type inference issues in macros #[doc(hidden)] pub fn terminatedc, F, G>(input: I, first: F, second: G) -> IResult where F: Fn(I) -> IResult, G: Fn(I) -> IResult, { terminated(first, second)(input) } /// Gets an object from the first parser, /// then matches an object from the sep_parser and discards it, /// then gets another object from the second parser. /// /// # Arguments /// * `first` The first parser to apply. /// * `sep` The separator parser to apply. /// * `second` The second parser to apply. /// ```rust /// # use nom::{Err, error::ErrorKind, Needed}; /// # use nom::Needed::Size; /// use nom::sequence::separated_pair; /// use nom::bytes::complete::tag; /// /// let parser = separated_pair(tag("abc"), tag("|"), tag("efg")); /// /// assert_eq!(parser("abc|efg"), Ok(("", ("abc", "efg")))); /// assert_eq!(parser("abc|efghij"), Ok(("hij", ("abc", "efg")))); /// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag)))); /// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag)))); /// ``` pub fn separated_pair, F, G, H>(first: F, sep: G, second: H) -> impl Fn(I) -> IResult where F: Fn(I) -> IResult, G: Fn(I) -> IResult, H: Fn(I) -> IResult, { move |input: I| { let (input, o1) = first(input)?; let (input, _) = sep(input)?; second(input).map(|(i, o2)| (i, (o1, o2))) } } // this implementation is used for type inference issues in macros #[doc(hidden)] pub fn separated_pairc, F, G, H>(input: I, first: F, sep: G, second: H) -> IResult where F: Fn(I) -> IResult, G: Fn(I) -> IResult, H: Fn(I) -> IResult, { separated_pair(first, sep, second)(input) } /// Matches an object from the first parser, /// then gets an object from the sep_parser, /// then matches another object from the second parser. /// /// # Arguments /// * `first` The first parser to apply. /// * `sep` The separator parser to apply. /// * `second` The second parser to apply. /// ```rust /// # use nom::{Err, error::ErrorKind, Needed}; /// # use nom::Needed::Size; /// use nom::sequence::delimited; /// use nom::bytes::complete::tag; /// /// let parser = delimited(tag("abc"), tag("|"), tag("efg")); /// /// assert_eq!(parser("abc|efg"), Ok(("", "|"))); /// assert_eq!(parser("abc|efghij"), Ok(("hij", "|"))); /// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag)))); /// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag)))); /// ``` pub fn delimited, F, G, H>(first: F, sep: G, second: H) -> impl Fn(I) -> IResult where F: Fn(I) -> IResult, G: Fn(I) -> IResult, H: Fn(I) -> IResult, { move |input: I| { let (input, _) = first(input)?; let (input, o2) = sep(input)?; second(input).map(|(i, _)| (i, o2)) } } // this implementation is used for type inference issues in macros #[doc(hidden)] pub fn delimitedc, F, G, H>(input: I, first: F, sep: G, second: H) -> IResult where F: Fn(I) -> IResult, G: Fn(I) -> IResult, H: Fn(I) -> IResult, { delimited(first, sep, second)(input) } /// helper trait for the tuple combinator /// /// this trait is implemented for tuples of parsers of up to 21 elements pub trait Tuple { /// parses the input and returns a tuple of results of each parser fn parse(&self, input: I) -> IResult; } impl, F: Fn(Input) -> IResult > Tuple for (F,) { fn parse(&self, input: Input) -> IResult { self.0(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),+) => ( impl< Input: Clone, $($ty),+ , Error: ParseError, $($name: Fn(Input) -> IResult),+ > Tuple for ( $($name),+ ) { fn parse(&self, input: Input) -> IResult { 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($input.clone())?; 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($input.clone())?; 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($input.clone())?; 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); /// applies a tuple of parsers one by one and returns their results as a tuple /// /// ```rust /// # use nom::{Err, error::ErrorKind}; /// use nom::sequence::tuple; /// use nom::character::complete::{alpha1, digit1}; /// let parser = tuple((alpha1, digit1, alpha1)); /// /// assert_eq!(parser("abc123def"), Ok(("", ("abc", "123", "def")))); /// assert_eq!(parser("123def"), Err(Err::Error(("123def", ErrorKind::Alpha)))); /// ``` pub fn tuple, List: Tuple>(l: List) -> impl Fn(I) -> IResult { move |i: I| { l.parse(i) } } #[cfg(test)] mod tests { use super::*; #[test] fn single_element_tuples() { use crate::character::complete::{alpha1, digit1}; use crate::{Err, error::ErrorKind}; let parser = tuple((alpha1,)); assert_eq!(parser("abc123def"), Ok(("123def", ("abc",)))); assert_eq!(parser("123def"), Err(Err::Error(("123def", ErrorKind::Alpha)))); } }