use crate::combinator::trace; use crate::error::ParserError; use crate::stream::Stream; use crate::*; #[doc(inline)] pub use crate::seq; /// Sequence two parsers, only returning the output from the second. /// /// See also [`seq`] to generalize this across any number of fields. /// /// # Example /// /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// use winnow::combinator::preceded; /// /// let mut parser = preceded("abc", "efg"); /// /// assert_eq!(parser.parse_peek("abcefg"), Ok(("", "efg"))); /// assert_eq!(parser.parse_peek("abcefghij"), Ok(("hij", "efg"))); /// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag)))); /// assert_eq!(parser.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag)))); /// ``` #[doc(alias = "ignore_then")] pub fn preceded( mut ignored: IgnoredParser, mut parser: ParseNext, ) -> impl Parser where Input: Stream, Error: ParserError, IgnoredParser: Parser, ParseNext: Parser, { trace("preceded", move |input: &mut Input| { let _ = ignored.parse_next(input)?; parser.parse_next(input) }) } /// Sequence two parsers, only returning the output of the first. /// /// See also [`seq`] to generalize this across any number of fields. /// /// # Example /// /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed}; /// # use winnow::prelude::*; /// # use winnow::error::Needed::Size; /// use winnow::combinator::terminated; /// /// let mut parser = terminated("abc", "efg"); /// /// assert_eq!(parser.parse_peek("abcefg"), Ok(("", "abc"))); /// assert_eq!(parser.parse_peek("abcefghij"), Ok(("hij", "abc"))); /// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag)))); /// assert_eq!(parser.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag)))); /// ``` #[doc(alias = "then_ignore")] pub fn terminated( mut parser: ParseNext, mut ignored: IgnoredParser, ) -> impl Parser where Input: Stream, Error: ParserError, ParseNext: Parser, IgnoredParser: Parser, { trace("terminated", move |input: &mut Input| { let o = parser.parse_next(input)?; ignored.parse_next(input).map(|_| o) }) } /// Sequence three parsers, only returning the values of the first and third. /// /// See also [`seq`] to generalize this across any number of fields. /// /// # Example /// /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed}; /// # use winnow::error::Needed::Size; /// # use winnow::prelude::*; /// use winnow::combinator::separated_pair; /// /// let mut parser = separated_pair("abc", "|", "efg"); /// /// assert_eq!(parser.parse_peek("abc|efg"), Ok(("", ("abc", "efg")))); /// assert_eq!(parser.parse_peek("abc|efghij"), Ok(("hij", ("abc", "efg")))); /// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag)))); /// assert_eq!(parser.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag)))); /// ``` pub fn separated_pair( mut first: P1, mut sep: SepParser, mut second: P2, ) -> impl Parser where Input: Stream, Error: ParserError, P1: Parser, SepParser: Parser, P2: Parser, { trace("separated_pair", move |input: &mut Input| { let o1 = first.parse_next(input)?; let _ = sep.parse_next(input)?; second.parse_next(input).map(|o2| (o1, o2)) }) } /// Sequence three parsers, only returning the output of the second. /// /// See also [`seq`] to generalize this across any number of fields. /// /// # Example /// /// ```rust /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed}; /// # use winnow::error::Needed::Size; /// # use winnow::prelude::*; /// use winnow::combinator::delimited; /// /// let mut parser = delimited("(", "abc", ")"); /// /// assert_eq!(parser.parse_peek("(abc)"), Ok(("", "abc"))); /// assert_eq!(parser.parse_peek("(abc)def"), Ok(("def", "abc"))); /// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag)))); /// assert_eq!(parser.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag)))); /// ``` #[doc(alias = "between")] #[doc(alias = "padded")] pub fn delimited< Input, Ignored1, Output, Ignored2, Error, IgnoredParser1, ParseNext, IgnoredParser2, >( mut ignored1: IgnoredParser1, mut parser: ParseNext, mut ignored2: IgnoredParser2, ) -> impl Parser where Input: Stream, Error: ParserError, IgnoredParser1: Parser, ParseNext: Parser, IgnoredParser2: Parser, { trace("delimited", move |input: &mut Input| { let _ = ignored1.parse_next(input)?; let o2 = parser.parse_next(input)?; ignored2.parse_next(input).map(|_| o2) }) }