use crate::error::ParseError; use crate::stream::Stream; use crate::trace::trace; use crate::*; /// Sequence two parsers, only returning the output from the second. /// /// # Arguments /// * `first` The opening parser. /// * `second` The second parser to get object. /// /// # Example /// /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// use winnow::combinator::preceded; /// use winnow::token::tag; /// /// let mut parser = preceded("abc", "efg"); /// /// assert_eq!(parser.parse_next("abcefg"), Ok(("", "efg"))); /// assert_eq!(parser.parse_next("abcefghij"), Ok(("hij", "efg"))); /// assert_eq!(parser.parse_next(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Tag)))); /// assert_eq!(parser.parse_next("123"), Err(ErrMode::Backtrack(Error::new("123", ErrorKind::Tag)))); /// ``` #[doc(alias = "ignore_then")] pub fn preceded, F, G>( mut first: F, mut second: G, ) -> impl Parser where I: Stream, F: Parser, G: Parser, { trace("preceded", move |input: I| { let (input, _) = first.parse_next(input)?; second.parse_next(input) }) } /// Sequence two parsers, only returning the output of the first. /// /// # Arguments /// * `first` The first parser to apply. /// * `second` The second parser to match an object. /// /// # Example /// /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// use winnow::combinator::terminated; /// use winnow::token::tag; /// /// let mut parser = terminated("abc", "efg"); /// /// assert_eq!(parser.parse_next("abcefg"), Ok(("", "abc"))); /// assert_eq!(parser.parse_next("abcefghij"), Ok(("hij", "abc"))); /// assert_eq!(parser.parse_next(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Tag)))); /// assert_eq!(parser.parse_next("123"), Err(ErrMode::Backtrack(Error::new("123", ErrorKind::Tag)))); /// ``` #[doc(alias = "then_ignore")] pub fn terminated, F, G>( mut first: F, mut second: G, ) -> impl Parser where I: Stream, F: Parser, G: Parser, { trace("terminated", move |input: I| { let (input, o1) = first.parse_next(input)?; second.parse_next(input).map(|(i, _)| (i, o1)) }) } /// Sequence three parsers, only returning the values of the first and third. /// /// # Arguments /// * `first` The first parser to apply. /// * `sep` The separator parser to apply. /// * `second` The second parser to apply. /// /// # Example /// /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::error::Needed::Size; /// # use winnow::prelude::*; /// use winnow::combinator::separated_pair; /// use winnow::token::tag; /// /// let mut parser = separated_pair("abc", "|", "efg"); /// /// assert_eq!(parser.parse_next("abc|efg"), Ok(("", ("abc", "efg")))); /// assert_eq!(parser.parse_next("abc|efghij"), Ok(("hij", ("abc", "efg")))); /// assert_eq!(parser.parse_next(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Tag)))); /// assert_eq!(parser.parse_next("123"), Err(ErrMode::Backtrack(Error::new("123", ErrorKind::Tag)))); /// ``` pub fn separated_pair, F, G, H>( mut first: F, mut sep: G, mut second: H, ) -> impl Parser where I: Stream, F: Parser, G: Parser, H: Parser, { trace("separated_pair", move |input: I| { let (input, o1) = first.parse_next(input)?; let (input, _) = sep.parse_next(input)?; second.parse_next(input).map(|(i, o2)| (i, (o1, o2))) }) } /// Sequence three parsers, only returning the output of the second. /// /// # Arguments /// * `first` The first parser to apply and discard. /// * `second` The second parser to apply. /// * `third` The third parser to apply and discard. /// /// # Example /// /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, error::Needed}; /// # use winnow::error::Needed::Size; /// # use winnow::prelude::*; /// use winnow::combinator::delimited; /// use winnow::token::tag; /// /// let mut parser = delimited("(", "abc", ")"); /// /// assert_eq!(parser.parse_next("(abc)"), Ok(("", "abc"))); /// assert_eq!(parser.parse_next("(abc)def"), Ok(("def", "abc"))); /// assert_eq!(parser.parse_next(""), Err(ErrMode::Backtrack(Error::new("", ErrorKind::Tag)))); /// assert_eq!(parser.parse_next("123"), Err(ErrMode::Backtrack(Error::new("123", ErrorKind::Tag)))); /// ``` #[doc(alias = "between")] #[doc(alias = "padded")] pub fn delimited, F, G, H>( mut first: F, mut second: G, mut third: H, ) -> impl Parser where I: Stream, F: Parser, G: Parser, H: Parser, { trace("delimited", move |input: I| { let (input, _) = first.parse_next(input)?; let (input, o2) = second.parse_next(input)?; third.parse_next(input).map(|(i, _)| (i, o2)) }) }