1use crate::combinator::trace;
2use crate::error::ParserError;
3use crate::stream::Stream;
4use crate::*;
5
6#[doc(inline)]
7pub use crate::seq;
8
9/// Sequence two parsers, only returning the output from the second.
10///
11/// See also [`seq`] to generalize this across any number of fields.
12///
13/// # Example
14///
15/// ```rust
16/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
17/// # use winnow::prelude::*;
18/// # use winnow::error::Needed::Size;
19/// use winnow::combinator::preceded;
20///
21/// let mut parser = preceded("abc", "efg");
22///
23/// assert_eq!(parser.parse_peek("abcefg"), Ok(("", "efg")));
24/// assert_eq!(parser.parse_peek("abcefghij"), Ok(("hij", "efg")));
25/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag))));
26/// assert_eq!(parser.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag))));
27/// ```
28#[doc(alias = "ignore_then")]
29pub fn preceded<Input, Ignored, Output, Error, IgnoredParser, ParseNext>(
30 mut ignored: IgnoredParser,
31 mut parser: ParseNext,
32) -> impl Parser<Input, Output, Error>
33where
34 Input: Stream,
35 Error: ParserError<Input>,
36 IgnoredParser: Parser<Input, Ignored, Error>,
37 ParseNext: Parser<Input, Output, Error>,
38{
39 trace(name:"preceded", parser:move |input: &mut Input| {
40 let _ = ignored.parse_next(input)?;
41 parser.parse_next(input)
42 })
43}
44
45/// Sequence two parsers, only returning the output of the first.
46///
47/// See also [`seq`] to generalize this across any number of fields.
48///
49/// # Example
50///
51/// ```rust
52/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
53/// # use winnow::prelude::*;
54/// # use winnow::error::Needed::Size;
55/// use winnow::combinator::terminated;
56///
57/// let mut parser = terminated("abc", "efg");
58///
59/// assert_eq!(parser.parse_peek("abcefg"), Ok(("", "abc")));
60/// assert_eq!(parser.parse_peek("abcefghij"), Ok(("hij", "abc")));
61/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag))));
62/// assert_eq!(parser.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag))));
63/// ```
64#[doc(alias = "then_ignore")]
65pub fn terminated<Input, Output, Ignored, Error, ParseNext, IgnoredParser>(
66 mut parser: ParseNext,
67 mut ignored: IgnoredParser,
68) -> impl Parser<Input, Output, Error>
69where
70 Input: Stream,
71 Error: ParserError<Input>,
72 ParseNext: Parser<Input, Output, Error>,
73 IgnoredParser: Parser<Input, Ignored, Error>,
74{
75 trace(name:"terminated", parser:move |input: &mut Input| {
76 let o: Output = parser.parse_next(input)?;
77 ignored.parse_next(input).map(|_| o)
78 })
79}
80
81/// Sequence three parsers, only returning the values of the first and third.
82///
83/// See also [`seq`] to generalize this across any number of fields.
84///
85/// # Example
86///
87/// ```rust
88/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
89/// # use winnow::error::Needed::Size;
90/// # use winnow::prelude::*;
91/// use winnow::combinator::separated_pair;
92///
93/// let mut parser = separated_pair("abc", "|", "efg");
94///
95/// assert_eq!(parser.parse_peek("abc|efg"), Ok(("", ("abc", "efg"))));
96/// assert_eq!(parser.parse_peek("abc|efghij"), Ok(("hij", ("abc", "efg"))));
97/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag))));
98/// assert_eq!(parser.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag))));
99/// ```
100pub fn separated_pair<Input, O1, Sep, O2, Error, P1, SepParser, P2>(
101 mut first: P1,
102 mut sep: SepParser,
103 mut second: P2,
104) -> impl Parser<Input, (O1, O2), Error>
105where
106 Input: Stream,
107 Error: ParserError<Input>,
108 P1: Parser<Input, O1, Error>,
109 SepParser: Parser<Input, Sep, Error>,
110 P2: Parser<Input, O2, Error>,
111{
112 trace(name:"separated_pair", parser:move |input: &mut Input| {
113 let o1: O1 = first.parse_next(input)?;
114 let _ = sep.parse_next(input)?;
115 second.parse_next(input).map(|o2: O2| (o1, o2))
116 })
117}
118
119/// Sequence three parsers, only returning the output of the second.
120///
121/// See also [`seq`] to generalize this across any number of fields.
122///
123/// # Example
124///
125/// ```rust
126/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
127/// # use winnow::error::Needed::Size;
128/// # use winnow::prelude::*;
129/// use winnow::combinator::delimited;
130///
131/// let mut parser = delimited("(", "abc", ")");
132///
133/// assert_eq!(parser.parse_peek("(abc)"), Ok(("", "abc")));
134/// assert_eq!(parser.parse_peek("(abc)def"), Ok(("def", "abc")));
135/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag))));
136/// assert_eq!(parser.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag))));
137/// ```
138#[doc(alias = "between")]
139#[doc(alias = "padded")]
140pub fn delimited<
141 Input,
142 Ignored1,
143 Output,
144 Ignored2,
145 Error,
146 IgnoredParser1,
147 ParseNext,
148 IgnoredParser2,
149>(
150 mut ignored1: IgnoredParser1,
151 mut parser: ParseNext,
152 mut ignored2: IgnoredParser2,
153) -> impl Parser<Input, Output, Error>
154where
155 Input: Stream,
156 Error: ParserError<Input>,
157 IgnoredParser1: Parser<Input, Ignored1, Error>,
158 ParseNext: Parser<Input, Output, Error>,
159 IgnoredParser2: Parser<Input, Ignored2, Error>,
160{
161 trace(name:"delimited", parser:move |input: &mut Input| {
162 let _ = ignored1.parse_next(input)?;
163 let o2: Output = parser.parse_next(input)?;
164 ignored2.parse_next(input).map(|_| o2)
165 })
166}
167