1 use crate::combinator::trace;
2 use crate::error::ParserError;
3 use crate::stream::Stream;
4 use crate::*;
5
6 #[doc(inline)]
7 pub 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")]
preceded<Input, Ignored, Output, Error, IgnoredParser, ParseNext>( mut ignored: IgnoredParser, mut parser: ParseNext, ) -> impl Parser<Input, Output, Error> where Input: Stream, Error: ParserError<Input>, IgnoredParser: Parser<Input, Ignored, Error>, ParseNext: Parser<Input, Output, Error>,29 pub fn preceded<Input, Ignored, Output, Error, IgnoredParser, ParseNext>(
30 mut ignored: IgnoredParser,
31 mut parser: ParseNext,
32 ) -> impl Parser<Input, Output, Error>
33 where
34 Input: Stream,
35 Error: ParserError<Input>,
36 IgnoredParser: Parser<Input, Ignored, Error>,
37 ParseNext: Parser<Input, Output, Error>,
38 {
39 trace("preceded", 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")]
terminated<Input, Output, Ignored, Error, ParseNext, IgnoredParser>( mut parser: ParseNext, mut ignored: IgnoredParser, ) -> impl Parser<Input, Output, Error> where Input: Stream, Error: ParserError<Input>, ParseNext: Parser<Input, Output, Error>, IgnoredParser: Parser<Input, Ignored, Error>,65 pub fn terminated<Input, Output, Ignored, Error, ParseNext, IgnoredParser>(
66 mut parser: ParseNext,
67 mut ignored: IgnoredParser,
68 ) -> impl Parser<Input, Output, Error>
69 where
70 Input: Stream,
71 Error: ParserError<Input>,
72 ParseNext: Parser<Input, Output, Error>,
73 IgnoredParser: Parser<Input, Ignored, Error>,
74 {
75 trace("terminated", move |input: &mut Input| {
76 let o = 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 /// ```
separated_pair<Input, O1, Sep, O2, Error, P1, SepParser, P2>( mut first: P1, mut sep: SepParser, mut second: P2, ) -> impl Parser<Input, (O1, O2), Error> where Input: Stream, Error: ParserError<Input>, P1: Parser<Input, O1, Error>, SepParser: Parser<Input, Sep, Error>, P2: Parser<Input, O2, Error>,100 pub 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>
105 where
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("separated_pair", move |input: &mut Input| {
113 let o1 = first.parse_next(input)?;
114 let _ = sep.parse_next(input)?;
115 second.parse_next(input).map(|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")]
delimited< Input, Ignored1, Output, Ignored2, Error, IgnoredParser1, ParseNext, IgnoredParser2, >( mut ignored1: IgnoredParser1, mut parser: ParseNext, mut ignored2: IgnoredParser2, ) -> impl Parser<Input, Output, Error> where Input: Stream, Error: ParserError<Input>, IgnoredParser1: Parser<Input, Ignored1, Error>, ParseNext: Parser<Input, Output, Error>, IgnoredParser2: Parser<Input, Ignored2, Error>,140 pub 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>
154 where
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("delimited", move |input: &mut Input| {
162 let _ = ignored1.parse_next(input)?;
163 let o2 = parser.parse_next(input)?;
164 ignored2.parse_next(input).map(|_| o2)
165 })
166 }
167