nom/branch/
mod.rs

1//! Choice combinators
2
3#[cfg(test)]
4mod tests;
5
6use core::marker::PhantomData;
7
8use crate::error::ErrorKind;
9use crate::error::ParseError;
10use crate::internal::{Err, Mode, Parser};
11
12/// Tests a list of parsers one by one until one succeeds.
13///
14/// It takes as argument either a tuple or an array of parsers. If using a
15/// tuple, there is a maximum of 21 parsers. If you need more, it is possible to
16/// use an array.
17///
18/// ```rust
19/// # use nom::error_position;
20/// # use nom::{Err,error::ErrorKind, Needed, IResult, Parser};
21/// use nom::character::complete::{alpha1, digit1};
22/// use nom::branch::alt;
23/// # fn main() {
24/// fn parser(input: &str) -> IResult<&str, &str> {
25///   alt((alpha1, digit1)).parse(input)
26/// };
27///
28/// // the first parser, alpha1, recognizes the input
29/// assert_eq!(parser("abc"), Ok(("", "abc")));
30///
31/// // the first parser returns an error, so alt tries the second one
32/// assert_eq!(parser("123456"), Ok(("", "123456")));
33///
34/// // both parsers failed, and with the default error type, alt will return the last error
35/// assert_eq!(parser(" "), Err(Err::Error(error_position!(" ", ErrorKind::Digit))));
36/// # }
37/// ```
38///
39/// With a custom error type, it is possible to have alt return the error of the parser
40/// that went the farthest in the input data
41pub fn alt<List>(l: List) -> Choice<List> {
42  Choice { parser: l }
43}
44
45/// Applies a list of parsers in any order.
46///
47/// Permutation will succeed if all of the child parsers succeeded.
48/// It takes as argument a tuple of parsers, and returns a
49/// tuple of the parser results.
50///
51/// ```rust
52/// # use nom::{Err,error::{Error, ErrorKind}, Needed, IResult, Parser};
53/// use nom::character::complete::{alpha1, digit1};
54/// use nom::branch::permutation;
55/// # fn main() {
56/// fn parser(input: &str) -> IResult<&str, (&str, &str)> {
57///   permutation((alpha1, digit1)).parse(input)
58/// }
59///
60/// // permutation recognizes alphabetic characters then digit
61/// assert_eq!(parser("abc123"), Ok(("", ("abc", "123"))));
62///
63/// // but also in inverse order
64/// assert_eq!(parser("123abc"), Ok(("", ("abc", "123"))));
65///
66/// // it will fail if one of the parsers failed
67/// assert_eq!(parser("abc;"), Err(Err::Error(Error::new(";", ErrorKind::Digit))));
68/// # }
69/// ```
70///
71/// The parsers are applied greedily: if there are multiple unapplied parsers
72/// that could parse the next slice of input, the first one is used.
73/// ```rust
74/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Parser};
75/// use nom::branch::permutation;
76/// use nom::character::complete::{anychar, char};
77///
78/// fn parser(input: &str) -> IResult<&str, (char, char)> {
79///   permutation((anychar, char('a'))).parse(input)
80/// }
81///
82/// // anychar parses 'b', then char('a') parses 'a'
83/// assert_eq!(parser("ba"), Ok(("", ('b', 'a'))));
84///
85/// // anychar parses 'a', then char('a') fails on 'b',
86/// // even though char('a') followed by anychar would succeed
87/// assert_eq!(parser("ab"), Err(Err::Error(Error::new("b", ErrorKind::Char))));
88/// ```
89///
90pub fn permutation<I: Clone, E: ParseError<I>, List>(list: List) -> Permutation<List, E> {
91  Permutation {
92    parser: list,
93    e: PhantomData,
94  }
95}
96
97macro_rules! alt_trait(
98  ($first:ident $second:ident $($id: ident)+) => (
99    alt_trait!(__impl $first $second; $($id)+);
100  );
101  (__impl $($current:ident)*; $head:ident $($id: ident)+) => (
102    alt_trait_impl!($($current)*);
103
104    alt_trait!(__impl $($current)* $head; $($id)+);
105  );
106  (__impl $($current:ident)*; $head:ident) => (
107    alt_trait_impl!($($current)*);
108    alt_trait_impl!($($current)* $head);
109  );
110);
111
112/// Wrapping structure for the [alt()] combinator implementation
113pub struct Choice<T> {
114  parser: T,
115}
116
117macro_rules! alt_trait_impl(
118  ($($id:ident)+) => (
119    impl<
120      Input: Clone, Output, Error: ParseError<Input>,
121      $($id: Parser<Input, Output = Output, Error = Error>),+
122    > Parser<Input> for Choice< ( $($id),+ )> {
123      type Output = Output;
124      type Error = Error;
125
126      #[inline(always)]
127      fn process<OM: crate::OutputMode>(
128        &mut self,
129        input: Input,
130      ) -> crate::PResult<OM, Input, Self::Output, Self::Error> {
131        match self.parser.0.process::<OM>(input.clone()) {
132          Ok(res) => Ok(res),
133          Err(Err::Failure(e))=> Err(Err::Failure(e)),
134          Err(Err::Incomplete(i))=> Err(Err::Incomplete(i)),
135          Err(Err::Error(e)) => alt_trait_inner!(1, self, input, e, $($id)+),
136        }
137      }
138    }
139  );
140);
141
142macro_rules! alt_trait_inner(
143  ($it:tt, $self:expr, $input:expr, $err:expr, $head:ident $($id:ident)+) => (
144    match $self.parser.$it.process::<OM>($input.clone()) {
145      Ok(res) => Ok(res),
146      Err(Err::Failure(e))=>Err(Err::Failure(e)),
147      Err(Err::Incomplete(i))=> Err(Err::Incomplete(i)),
148      Err(Err::Error(e)) => {
149        succ!($it, alt_trait_inner!($self, $input, <OM::Error as crate::Mode>::combine($err, e, |e1, e2| e1.or(e2)), $($id)+))
150      }
151    }
152  );
153  ($it:tt, $self:expr, $input:expr, $err:expr, $head:ident) => (
154    Err(Err::Error(<OM::Error as crate::Mode>::map($err, |err| Error::append($input, ErrorKind::Alt, err))))
155  );
156);
157
158alt_trait!(A B C D E F G H I J K L M N O P Q R S T U);
159
160// Manually implement Alt for (A,), the 1-tuple type
161impl<Input, Output, Error: ParseError<Input>, A: Parser<Input, Output = Output, Error = Error>>
162  Parser<Input> for Choice<(A,)>
163{
164  type Output = Output;
165  type Error = Error;
166
167  #[inline]
168  fn process<OM: crate::OutputMode>(
169    &mut self,
170    input: Input,
171  ) -> crate::PResult<OM, Input, Self::Output, Self::Error> {
172    self.parser.0.process::<OM>(input)
173  }
174}
175
176impl<
177    const N: usize,
178    Input: Clone,
179    Output,
180    Error: ParseError<Input>,
181    A: Parser<Input, Output = Output, Error = Error>,
182  > Parser<Input> for Choice<[A; N]>
183{
184  type Output = Output;
185  type Error = Error;
186
187  #[inline]
188  fn process<OM: crate::OutputMode>(
189    &mut self,
190    input: Input,
191  ) -> crate::PResult<OM, Input, Self::Output, Self::Error> {
192    let mut error = None;
193
194    for branch in &mut self.parser {
195      match branch.process::<OM>(input.clone()) {
196        Err(Err::Error(e)) => match error {
197          None => error = Some(e),
198          Some(err) => error = Some(OM::Error::combine(err, e, |e1, e2| e1.or(e2))),
199        },
200        res => return res,
201      }
202    }
203
204    match error {
205      Some(e) => Err(Err::Error(OM::Error::map(e, |err| {
206        Error::append(input, ErrorKind::Alt, err)
207      }))),
208      None => Err(Err::Error(OM::Error::bind(|| {
209        Error::from_error_kind(input, ErrorKind::Alt)
210      }))),
211    }
212  }
213}
214
215impl<
216    Input: Clone,
217    Output,
218    Error: ParseError<Input>,
219    A: Parser<Input, Output = Output, Error = Error>,
220  > Parser<Input> for Choice<&mut [A]>
221{
222  type Output = Output;
223  type Error = Error;
224
225  #[inline]
226  fn process<OM: crate::OutputMode>(
227    &mut self,
228    input: Input,
229  ) -> crate::PResult<OM, Input, Self::Output, Self::Error> {
230    let mut error = None;
231
232    for branch in self.parser.iter_mut() {
233      match branch.process::<OM>(input.clone()) {
234        Err(Err::Error(e)) => match error {
235          None => error = Some(e),
236          Some(err) => error = Some(OM::Error::combine(err, e, |e1, e2| e1.or(e2))),
237        },
238        res => return res,
239      }
240    }
241
242    match error {
243      Some(e) => Err(Err::Error(OM::Error::map(e, |err| {
244        Error::append(input, ErrorKind::Alt, err)
245      }))),
246      None => Err(Err::Error(OM::Error::bind(|| {
247        Error::from_error_kind(input, ErrorKind::Alt)
248      }))),
249    }
250  }
251}
252
253macro_rules! permutation_trait(
254  (
255    $name1:ident $ty1:ident $item1:ident
256    $name2:ident $ty2:ident $item2:ident
257    $($name3:ident $ty3:ident $item3:ident)*
258  ) => (
259    permutation_trait!(__impl $name1 $ty1 $item1, $name2 $ty2 $item2; $($name3 $ty3 $item3)*);
260  );
261  (
262    __impl $($name:ident $ty:ident $item:ident),+;
263    $name1:ident $ty1:ident $item1:ident $($name2:ident $ty2:ident $item2:ident)*
264  ) => (
265    permutation_trait_impl!($($name $ty $item),+);
266    permutation_trait!(__impl $($name $ty $item),+ , $name1 $ty1 $item1; $($name2 $ty2 $item2)*);
267  );
268  (__impl $($name:ident $ty:ident $item:ident),+;) => (
269    permutation_trait_impl!($($name $ty $item),+);
270  );
271);
272
273/// Wrapping structure for the [permutation] combinator implementation
274pub struct Permutation<T, Error> {
275  parser: T,
276  e: PhantomData<Error>,
277}
278
279macro_rules! permutation_trait_impl(
280  ($($name:ident $ty:ident $item:ident),+) => (
281    impl<
282      Input, Error, $($ty),+ , $($name),+
283    > Parser<Input> for Permutation< ( $($name),+ ), Error>
284    where
285    Input: Clone,
286    Error: ParseError<Input>,
287    $($name: Parser<Input, Output = $ty, Error = Error>),+
288    {
289      type Output = ( $($ty),+ );
290      type Error = Error;
291
292      #[inline(always)]
293      fn process<OM: crate::OutputMode>(
294        &mut self,
295        mut input: Input,
296      ) -> crate::PResult<OM, Input, Self::Output, Self::Error> {
297        let mut res = OM::Output::bind(|| ($(Option::<$ty>::None),+));
298        $(let mut $item = false;)+
299
300        loop {
301          let mut err: Option<<OM::Error as Mode>::Output<Error>> = None;
302          permutation_trait_inner!(0, self, input, res,  err, $($item)+);
303
304          // If we reach here, every iterator has either been applied before,
305          // or errored on the remaining input
306          if let Some(err) = err {
307            // There are remaining parsers, and all errored on the remaining input
308            return Err(Err::Error(OM::Error::map(err, |err| Error::append(input, ErrorKind::Permutation, err))));
309          }
310
311          return Ok((input,OM::Output::map(res, |res| {
312            // All parsers were applied
313            match res {
314              ($(Some($item)),+) =>  ($($item),+),
315              _ => unreachable!(),
316            }
317          })))
318        }
319      }
320
321    }
322  );
323);
324
325macro_rules! permutation_trait_inner(
326  ($it:tt, $self:expr, $input:ident, $res:expr,  $err:expr, $head:ident $($item:ident)*) => (
327    if !$head {
328
329      match $self.parser.$it.process::<OM>($input.clone()) {
330        Ok((i, o)) => {
331          $input = i;
332          $res = OM::Output::combine($res, o, |mut res, o | {res.$it = Some(o);res });
333          $head = true;
334          continue;
335        }
336        Err(Err::Error(e)) => {
337          $err = Some(match $err {
338            None => e,
339            Some(err) => OM::Error::combine(err, e, |err, e| err.or(e))
340          });
341        }
342        Err(e) => return Err(e),
343      };
344    }
345    succ!($it, permutation_trait_inner!($self, $input, $res, $err, $($item)*));
346  );
347  ($it:tt, $self:expr, $input:ident, $res:expr, $err:expr,) => ();
348);
349
350permutation_trait!(
351  FnA A a
352  FnB B b
353  FnC C c
354  FnD D d
355  FnE E e
356  FnF F f
357  FnG G g
358  FnH H h
359  FnI I i
360  FnJ J j
361  FnK K k
362  FnL L l
363  FnM M m
364  FnN N n
365  FnO O o
366  FnP P p
367  FnQ Q q
368  FnR R r
369  FnS S s
370  FnT T t
371  FnU U u
372);