nom8/sequence/mod.rs
1//! Combinators applying parsers in sequence
2
3#[cfg(test)]
4mod tests;
5
6use crate::error::ParseError;
7use crate::{IResult, Parser};
8
9/// Gets an object from the first parser,
10/// then gets another object from the second parser.
11///
12/// **WARNING:** Deprecated, [`Parser`] is directly implemented for tuples
13///
14/// # Arguments
15/// * `first` The first parser to apply.
16/// * `second` The second parser to apply.
17///
18/// ```rust
19/// # use nom8::{Err, error::ErrorKind, Needed};
20/// # use nom8::Needed::Size;
21/// use nom8::sequence::pair;
22/// use nom8::bytes::tag;
23///
24/// let mut parser = pair(tag("abc"), tag("efg"));
25///
26/// assert_eq!(parser("abcefg"), Ok(("", ("abc", "efg"))));
27/// assert_eq!(parser("abcefghij"), Ok(("hij", ("abc", "efg"))));
28/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
29/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
30/// ```
31#[deprecated(since = "8.0.0", note = "`Parser` is directly implemented for tuples")]
32pub fn pair<I, O1, O2, E: ParseError<I>, F, G>(
33 mut first: F,
34 mut second: G,
35) -> impl FnMut(I) -> IResult<I, (O1, O2), E>
36where
37 F: Parser<I, O1, E>,
38 G: Parser<I, O2, E>,
39{
40 move |input: I| {
41 let (input, o1) = first.parse(input)?;
42 second.parse(input).map(|(i, o2)| (i, (o1, o2)))
43 }
44}
45
46/// Matches an object from the first parser and discards it,
47/// then gets an object from the second parser.
48///
49/// # Arguments
50/// * `first` The opening parser.
51/// * `second` The second parser to get object.
52///
53/// ```rust
54/// # use nom8::{Err, error::ErrorKind, Needed};
55/// # use nom8::Needed::Size;
56/// use nom8::sequence::preceded;
57/// use nom8::bytes::tag;
58///
59/// let mut parser = preceded(tag("abc"), tag("efg"));
60///
61/// assert_eq!(parser("abcefg"), Ok(("", "efg")));
62/// assert_eq!(parser("abcefghij"), Ok(("hij", "efg")));
63/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
64/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
65/// ```
66pub fn preceded<I, O1, O2, E: ParseError<I>, F, G>(
67 mut first: F,
68 mut second: G,
69) -> impl FnMut(I) -> IResult<I, O2, E>
70where
71 F: Parser<I, O1, E>,
72 G: Parser<I, O2, E>,
73{
74 move |input: I| {
75 let (input, _) = first.parse(input)?;
76 second.parse(input)
77 }
78}
79
80/// Gets an object from the first parser,
81/// then matches an object from the second parser and discards it.
82///
83/// # Arguments
84/// * `first` The first parser to apply.
85/// * `second` The second parser to match an object.
86///
87/// ```rust
88/// # use nom8::{Err, error::ErrorKind, Needed};
89/// # use nom8::Needed::Size;
90/// use nom8::sequence::terminated;
91/// use nom8::bytes::tag;
92///
93/// let mut parser = terminated(tag("abc"), tag("efg"));
94///
95/// assert_eq!(parser("abcefg"), Ok(("", "abc")));
96/// assert_eq!(parser("abcefghij"), Ok(("hij", "abc")));
97/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
98/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
99/// ```
100pub fn terminated<I, O1, O2, E: ParseError<I>, F, G>(
101 mut first: F,
102 mut second: G,
103) -> impl FnMut(I) -> IResult<I, O1, E>
104where
105 F: Parser<I, O1, E>,
106 G: Parser<I, O2, E>,
107{
108 move |input: I| {
109 let (input, o1) = first.parse(input)?;
110 second.parse(input).map(|(i, _)| (i, o1))
111 }
112}
113
114/// Gets an object from the first parser,
115/// then matches an object from the sep_parser and discards it,
116/// then gets another object from the second parser.
117///
118/// # Arguments
119/// * `first` The first parser to apply.
120/// * `sep` The separator parser to apply.
121/// * `second` The second parser to apply.
122///
123/// ```rust
124/// # use nom8::{Err, error::ErrorKind, Needed};
125/// # use nom8::Needed::Size;
126/// use nom8::sequence::separated_pair;
127/// use nom8::bytes::tag;
128///
129/// let mut parser = separated_pair(tag("abc"), tag("|"), tag("efg"));
130///
131/// assert_eq!(parser("abc|efg"), Ok(("", ("abc", "efg"))));
132/// assert_eq!(parser("abc|efghij"), Ok(("hij", ("abc", "efg"))));
133/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
134/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
135/// ```
136pub fn separated_pair<I, O1, O2, O3, E: ParseError<I>, F, G, H>(
137 mut first: F,
138 mut sep: G,
139 mut second: H,
140) -> impl FnMut(I) -> IResult<I, (O1, O3), E>
141where
142 F: Parser<I, O1, E>,
143 G: Parser<I, O2, E>,
144 H: Parser<I, O3, E>,
145{
146 move |input: I| {
147 let (input, o1) = first.parse(input)?;
148 let (input, _) = sep.parse(input)?;
149 second.parse(input).map(|(i, o2)| (i, (o1, o2)))
150 }
151}
152
153/// Matches an object from the first parser and discards it,
154/// then gets an object from the second parser,
155/// and finally matches an object from the third parser and discards it.
156///
157/// # Arguments
158/// * `first` The first parser to apply and discard.
159/// * `second` The second parser to apply.
160/// * `third` The third parser to apply and discard.
161///
162/// ```rust
163/// # use nom8::{Err, error::ErrorKind, Needed};
164/// # use nom8::Needed::Size;
165/// use nom8::sequence::delimited;
166/// use nom8::bytes::tag;
167///
168/// let mut parser = delimited(tag("("), tag("abc"), tag(")"));
169///
170/// assert_eq!(parser("(abc)"), Ok(("", "abc")));
171/// assert_eq!(parser("(abc)def"), Ok(("def", "abc")));
172/// assert_eq!(parser(""), Err(Err::Error(("", ErrorKind::Tag))));
173/// assert_eq!(parser("123"), Err(Err::Error(("123", ErrorKind::Tag))));
174/// ```
175pub fn delimited<I, O1, O2, O3, E: ParseError<I>, F, G, H>(
176 mut first: F,
177 mut second: G,
178 mut third: H,
179) -> impl FnMut(I) -> IResult<I, O2, E>
180where
181 F: Parser<I, O1, E>,
182 G: Parser<I, O2, E>,
183 H: Parser<I, O3, E>,
184{
185 move |input: I| {
186 let (input, _) = first.parse(input)?;
187 let (input, o2) = second.parse(input)?;
188 third.parse(input).map(|(i, _)| (i, o2))
189 }
190}
191
192/// Helper trait for the tuple combinator.
193///
194/// This trait is implemented for tuples of parsers of up to 21 elements.
195#[deprecated(since = "8.0.0", note = "Replaced with `Parser`")]
196pub trait Tuple<I, O, E> {
197 /// Parses the input and returns a tuple of results of each parser.
198 fn parse(&mut self, input: I) -> IResult<I, O, E>;
199}
200
201#[allow(deprecated)]
202impl<Input, Output, Error: ParseError<Input>, F: Parser<Input, Output, Error>>
203 Tuple<Input, (Output,), Error> for (F,)
204{
205 fn parse(&mut self, input: Input) -> IResult<Input, (Output,), Error> {
206 self.0.parse(input).map(|(i, o)| (i, (o,)))
207 }
208}
209
210macro_rules! tuple_trait(
211 ($name1:ident $ty1:ident, $name2: ident $ty2:ident, $($name:ident $ty:ident),*) => (
212 tuple_trait!(__impl $name1 $ty1, $name2 $ty2; $($name $ty),*);
213 );
214 (__impl $($name:ident $ty: ident),+; $name1:ident $ty1:ident, $($name2:ident $ty2:ident),*) => (
215 tuple_trait_impl!($($name $ty),+);
216 tuple_trait!(__impl $($name $ty),+ , $name1 $ty1; $($name2 $ty2),*);
217 );
218 (__impl $($name:ident $ty: ident),+; $name1:ident $ty1:ident) => (
219 tuple_trait_impl!($($name $ty),+);
220 tuple_trait_impl!($($name $ty),+, $name1 $ty1);
221 );
222);
223
224macro_rules! tuple_trait_impl(
225 ($($name:ident $ty: ident),+) => (
226 #[allow(deprecated)]
227 impl<
228 Input: Clone, $($ty),+ , Error: ParseError<Input>,
229 $($name: Parser<Input, $ty, Error>),+
230 > Tuple<Input, ( $($ty),+ ), Error> for ( $($name),+ ) {
231
232 fn parse(&mut self, input: Input) -> IResult<Input, ( $($ty),+ ), Error> {
233 tuple_trait_inner!(0, self, input, (), $($name)+)
234
235 }
236 }
237 );
238);
239
240macro_rules! tuple_trait_inner(
241 ($it:tt, $self:expr, $input:expr, (), $head:ident $($id:ident)+) => ({
242 let (i, o) = $self.$it.parse($input.clone())?;
243
244 succ!($it, tuple_trait_inner!($self, i, ( o ), $($id)+))
245 });
246 ($it:tt, $self:expr, $input:expr, ($($parsed:tt)*), $head:ident $($id:ident)+) => ({
247 let (i, o) = $self.$it.parse($input.clone())?;
248
249 succ!($it, tuple_trait_inner!($self, i, ($($parsed)* , o), $($id)+))
250 });
251 ($it:tt, $self:expr, $input:expr, ($($parsed:tt)*), $head:ident) => ({
252 let (i, o) = $self.$it.parse($input.clone())?;
253
254 Ok((i, ($($parsed)* , o)))
255 });
256);
257
258tuple_trait!(FnA A, FnB B, FnC C, FnD D, FnE E, FnF F, FnG G, FnH H, FnI I, FnJ J, FnK K, FnL L,
259 FnM M, FnN N, FnO O, FnP P, FnQ Q, FnR R, FnS S, FnT T, FnU U);
260
261// Special case: implement `Tuple` for `()`, the unit type.
262// This can come up in macros which accept a variable number of arguments.
263// Literally, `()` is an empty tuple, so it should simply parse nothing.
264#[allow(deprecated)]
265impl<I, E: ParseError<I>> Tuple<I, (), E> for () {
266 fn parse(&mut self, input: I) -> IResult<I, (), E> {
267 Ok((input, ()))
268 }
269}
270
271///Applies a tuple of parsers one by one and returns their results as a tuple.
272///There is a maximum of 21 parsers
273///
274/// **WARNING:** Deprecated, [`Parser`] is directly implemented for tuples
275///
276/// ```rust
277/// # use nom8::{Err, error::ErrorKind};
278/// use nom8::sequence::tuple;
279/// use nom8::character::{alpha1, digit1};
280/// let mut parser = tuple((alpha1, digit1, alpha1));
281///
282/// assert_eq!(parser("abc123def"), Ok(("", ("abc", "123", "def"))));
283/// assert_eq!(parser("123def"), Err(Err::Error(("123def", ErrorKind::Alpha))));
284/// ```
285#[deprecated(since = "8.0.0", note = "`Parser` is directly implemented for tuples")]
286#[allow(deprecated)]
287pub fn tuple<I, O, E: ParseError<I>, List: Tuple<I, O, E>>(
288 mut l: List,
289) -> impl FnMut(I) -> IResult<I, O, E> {
290 move |i: I| l.parse(i)
291}