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