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}