1#[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
12pub fn alt<List>(l: List) -> Choice<List> {
42  Choice { parser: l }
43}
44
45pub 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
112pub 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
160impl<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
273pub 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 let Some(err) = err {
307            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            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);