1 //! Combinators which take one or more parsers and attempts to parse successfully with at least one
2 //! of them.
3 
4 use crate::{
5     error::{
6         ParseError,
7         ParseResult::{self, *},
8         ResultExt, StreamError, Tracked,
9     },
10     parser::ParseMode,
11     ErrorOffset, Parser, Stream, StreamOnce,
12 };
13 
14 /// Takes a number of parsers and tries to apply them each in order.
15 /// Fails if all the parsers fails or if an applied parser fails after it has committed to its
16 /// parse.
17 ///
18 /// ```
19 /// # #[macro_use]
20 /// # extern crate combine;
21 /// # use combine::*;
22 /// # use combine::parser::char::{digit, letter, string};
23 /// # use combine::stream::easy::Error;
24 /// # fn main() {
25 /// let mut parser = choice!(
26 ///     many1(digit()),
27 ///     string("let").map(|s| s.to_string()),
28 ///     many1(letter()));
29 /// assert_eq!(parser.parse("let"), Ok(("let".to_string(), "")));
30 /// assert_eq!(parser.parse("123abc"), Ok(("123".to_string(), "abc")));
31 /// assert!(parser.parse(":123").is_err());
32 /// # }
33 /// ```
34 #[macro_export]
35 macro_rules! choice {
36     ($first : expr) => {
37         $first
38     };
39     ($first : expr, $($rest : expr),+) => {
40         $first.or(choice!($($rest),+))
41     }
42 }
43 
44 #[macro_export]
45 #[doc(hidden)]
46 macro_rules! parse_mode_choice {
47     (Input) => {
48         fn parse_partial(
49             &mut self,
50             input: &mut Input,
51             state: &mut Self::PartialState,
52         ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
53             self.parse_mode_choice($crate::parser::PartialMode::default(), input, state)
54         }
55 
56         fn parse_first(
57             &mut self,
58             input: &mut Input,
59             state: &mut Self::PartialState,
60         ) -> ParseResult<Self::Output, Input::Error> {
61             self.parse_mode_choice($crate::parser::FirstMode, input, state)
62         }
63     };
64 }
65 
66 /// `ChoiceParser` represents a parser which may parse one of several different choices depending
67 /// on the input.
68 ///
69 /// This is an internal trait used to overload the `choice` function.
70 pub trait ChoiceParser<Input: Stream> {
71     type Output;
72     type PartialState: Default;
73 
parse_first( &mut self, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>74     fn parse_first(
75         &mut self,
76         input: &mut Input,
77         state: &mut Self::PartialState,
78     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>;
79 
parse_partial( &mut self, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>80     fn parse_partial(
81         &mut self,
82         input: &mut Input,
83         state: &mut Self::PartialState,
84     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>;
85 
parse_mode_choice<M>( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode, Self: Sized86     fn parse_mode_choice<M>(
87         &mut self,
88         mode: M,
89         input: &mut Input,
90         state: &mut Self::PartialState,
91     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
92     where
93         M: ParseMode,
94         Self: Sized;
95 
add_error_choice(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>)96     fn add_error_choice(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>);
97 }
98 
99 impl<'a, Input, P> ChoiceParser<Input> for &'a mut P
100 where
101     Input: Stream,
102     P: ?Sized + ChoiceParser<Input>,
103 {
104     type Output = P::Output;
105     type PartialState = P::PartialState;
106 
107     parse_mode_choice!(Input);
108     #[inline]
parse_mode_choice<M>( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,109     fn parse_mode_choice<M>(
110         &mut self,
111         mode: M,
112         input: &mut Input,
113         state: &mut Self::PartialState,
114     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
115     where
116         M: ParseMode,
117     {
118         if mode.is_first() {
119             (**self).parse_first(input, state)
120         } else {
121             (**self).parse_partial(input, state)
122         }
123     }
124 
add_error_choice(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>)125     fn add_error_choice(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) {
126         (**self).add_error_choice(error)
127     }
128 }
129 
130 macro_rules! merge {
131     ($head: ident) => {
132         $head.error
133     };
134     ($head: ident $($tail: ident)+) => {
135         $head.error.merge(merge!($($tail)+))
136     };
137 }
138 
139 macro_rules! do_choice {
140     (
141         $input: ident
142         $before_position: ident
143         $before: ident
144         $partial_state: ident
145         $state: ident
146         ( )
147         $($parser: ident $error: ident)+
148     ) => { {
149         let mut error = Tracked::from(merge!($($error)+));
150         // If offset != 1 then the nested parser is a sequence of parsers where 1 or
151         // more parsers returned `PeekOk` before the parser finally failed with
152         // `PeekErr`. Since we lose the offsets of the nested parsers when we merge
153         // the errors we must first extract the errors before we do the merge.
154         // If the offset == 0 on the other hand (which should be the common case) then
155         // we can delay the addition of the error since we know for certain that only
156         // the first parser in the sequence were tried
157         $(
158             if $error.offset != ErrorOffset(1) {
159                 error.offset = $error.offset;
160                 $parser.add_error(&mut error);
161                 error.offset = ErrorOffset(0);
162             }
163         )+
164         PeekErr(error)
165     } };
166     (
167         $input: ident
168         $before_position: ident
169         $before: ident
170         $partial_state: ident
171         $state: ident
172         ( $head: ident $($tail: ident)* )
173         $($all: ident)*
174     ) => { {
175         let parser = $head;
176         let mut state = $head::PartialState::default();
177         match parser.parse_mode(crate::parser::FirstMode, $input, &mut state) {
178             CommitOk(x) => CommitOk(x),
179             PeekOk(x) => PeekOk(x),
180             CommitErr(err) => {
181                 // If we get `CommitErr` but the input is the same this is a partial parse we
182                 // cannot commit to so leave the state as `Peek` to retry all the parsers
183                 // on the next call to  `parse_partial`
184                 if $input.position() != $before_position {
185                     *$state = self::$partial_state::$head(state);
186                 }
187                 CommitErr(err)
188             }
189             PeekErr($head) => {
190                 ctry!($input.reset($before.clone()).committed());
191                 do_choice!(
192                     $input
193                     $before_position
194                     $before
195                     $partial_state
196                     $state
197                     ( $($tail)* )
198                     $($all)*
199                     parser
200                     $head
201                 )
202             }
203         }
204     } }
205 }
206 
207 macro_rules! tuple_choice_parser {
208     ($head: ident) => {
209         tuple_choice_parser_inner!($head; $head);
210     };
211     ($head: ident $($id: ident)+) => {
212         tuple_choice_parser_inner!($head; $head $($id)+);
213         tuple_choice_parser!($($id)+);
214     };
215 }
216 
217 macro_rules! tuple_choice_parser_inner {
218     ($partial_state: ident; $($id: ident)+) => {
219         #[doc(hidden)]
220         pub enum $partial_state<$($id),+> {
221             Peek,
222             $(
223                 $id($id),
224             )+
225         }
226 
227         impl<$($id),+> Default for self::$partial_state<$($id),+> {
228             fn default() -> Self {
229                 self::$partial_state::Peek
230             }
231         }
232 
233         #[allow(non_snake_case)]
234         impl<Input, Output $(,$id)+> ChoiceParser<Input> for ($($id,)+)
235         where
236             Input: Stream,
237             $($id: Parser< Input, Output = Output>),+
238         {
239 
240             type Output = Output;
241             type PartialState = self::$partial_state<$($id::PartialState),+>;
242 
243             parse_mode_choice!(Input);
244             #[inline]
245             fn parse_mode_choice<Mode>(
246                 &mut self,
247                 mode: Mode,
248                 input: &mut Input,
249                 state: &mut Self::PartialState,
250             ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
251             where
252                 Mode: ParseMode,
253             {
254                 let ($(ref mut $id,)+) = *self;
255                 let empty = match *state {
256                     self::$partial_state::Peek => true,
257                     _ => false,
258                 };
259                 if mode.is_first() || empty {
260                     let before_position = input.position();
261                     let before = input.checkpoint();
262                     do_choice!(input before_position before $partial_state state ( $($id)+ ) )
263                 } else {
264                     match *state {
265                         self::$partial_state::Peek => unreachable!(),
266                         $(
267                             self::$partial_state::$id(_) => {
268                                 let result = match *state {
269                                     self::$partial_state::$id(ref mut state) => {
270                                         $id.parse_mode(mode, input, state)
271                                     }
272                                     _ => unreachable!()
273                                 };
274                                 if result.is_ok() {
275                                     *state = self::$partial_state::Peek;
276                                 }
277                                 result
278                             }
279                         )+
280                     }
281                 }
282             }
283 
284             fn add_error_choice(
285                 &mut self,
286                 error: &mut Tracked<<Input as StreamOnce>::Error>
287             ) {
288                 if error.offset != ErrorOffset(0) {
289                     let ($(ref mut $id,)+) = *self;
290                     // Reset the offset to 1 on every add so that we always (and only) takes the
291                     // error of the first parser. If we don't do this the first parser will consume
292                     // the offset to the detriment for all the other parsers.
293                     $(
294                         error.offset = ErrorOffset(1);
295                         $id.add_error(error);
296                     )+
297                 }
298             }
299         }
300     }
301 }
302 
303 tuple_choice_parser!(A B C D E F G H I J K L M N O P Q R S T U V X Y Z);
304 
305 macro_rules! array_choice_parser {
306     ($($t: tt)+) => {
307         $(
308         impl<Input, P> ChoiceParser<Input> for [P; $t]
309         where
310             Input: Stream,
311             P: Parser<Input>,
312         {
313 
314             type Output = P::Output;
315             type PartialState = <[P] as ChoiceParser<Input>>::PartialState;
316 
317             parse_mode_choice!(Input);
318             #[inline]
319             fn parse_mode_choice<M>(
320                 &mut self,
321                 mode: M,
322                 input: &mut Input,
323                 state: &mut Self::PartialState,
324             ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
325             where
326                 M: ParseMode,
327             {
328                 if mode.is_first() {
329                     self[..].parse_first(input, state)
330                 } else {
331                     self[..].parse_partial(input, state)
332                 }
333             }
334             fn add_error_choice(
335                 &mut self,
336                 error: &mut Tracked<<Input as StreamOnce>::Error>
337             ) {
338                 self[..].add_error_choice(error)
339             }
340         }
341         )+
342     };
343 }
344 
345 #[rustfmt::skip]
346 array_choice_parser!(
347     0 1 2 3 4 5 6 7 8 9
348     10 11 12 13 14 15 16 17 18 19
349     20 21 22 23 24 25 26 27 28 29
350     30 31 32
351 );
352 
353 #[derive(Copy, Clone)]
354 pub struct Choice<P>(P);
355 
356 impl<Input, P> Parser<Input> for Choice<P>
357 where
358     Input: Stream,
359     P: ChoiceParser<Input>,
360 {
361     type Output = P::Output;
362     type PartialState = P::PartialState;
363 
364     parse_mode!(Input);
365     #[inline]
parse_mode_impl<M>( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,366     fn parse_mode_impl<M>(
367         &mut self,
368         mode: M,
369         input: &mut Input,
370         state: &mut Self::PartialState,
371     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
372     where
373         M: ParseMode,
374     {
375         self.0.parse_mode_choice(mode, input, state)
376     }
377 
add_error(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>)378     fn add_error(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) {
379         let before = error.offset.0;
380         self.0.add_error_choice(error);
381         error.offset.0 = before.saturating_sub(1);
382     }
383 }
384 
slice_parse_mode<Input, P, M>( self_: &mut [P], mode: M, input: &mut Input, state: &mut (usize, P::PartialState), ) -> ParseResult<P::Output, <Input as StreamOnce>::Error> where P: Parser<Input>, Input: Stream, M: ParseMode,385 fn slice_parse_mode<Input, P, M>(
386     self_: &mut [P],
387     mode: M,
388     input: &mut Input,
389     state: &mut (usize, P::PartialState),
390 ) -> ParseResult<P::Output, <Input as StreamOnce>::Error>
391 where
392     P: Parser<Input>,
393     Input: Stream,
394     M: ParseMode,
395 {
396     let mut prev_err = None;
397     let mut last_parser_having_non_1_offset = 0;
398     let before = input.checkpoint();
399 
400     let (ref mut index_state, ref mut child_state) = *state;
401     if !mode.is_first() && *index_state != 0 {
402         return self_[*index_state - 1]
403             .parse_partial(input, child_state)
404             .map(|x| {
405                 *index_state = 0;
406                 x
407             });
408     }
409 
410     for i in 0..self_.len() {
411         ctry!(input.reset(before.clone()).committed());
412 
413         match self_[i].parse_mode(mode, input, child_state) {
414             committed_err @ CommitErr(_) => {
415                 *index_state = i + 1;
416                 return committed_err;
417             }
418             PeekErr(err) => {
419                 prev_err = match prev_err {
420                     None => Some(err),
421                     Some(mut prev_err) => {
422                         if prev_err.offset != ErrorOffset(1) {
423                             // First add the errors of all the preceding parsers which did not
424                             // have a sequence of parsers returning `PeekOk` before failing
425                             // with `PeekErr`.
426                             let offset = prev_err.offset;
427                             for p in &mut self_[last_parser_having_non_1_offset..(i - 1)] {
428                                 prev_err.offset = ErrorOffset(1);
429                                 p.add_error(&mut prev_err);
430                             }
431                             // Then add the errors if the current parser
432                             prev_err.offset = offset;
433                             self_[i - 1].add_error(&mut prev_err);
434                             last_parser_having_non_1_offset = i;
435                         }
436                         Some(Tracked {
437                             error: prev_err.error.merge(err.error),
438                             offset: err.offset,
439                         })
440                     }
441                 };
442             }
443             ok @ CommitOk(_) | ok @ PeekOk(_) => {
444                 *index_state = 0;
445                 return ok;
446             }
447         }
448     }
449     PeekErr(match prev_err {
450         None => Input::Error::from_error(
451             input.position(),
452             StreamError::message_static_message("parser choice is empty"),
453         )
454         .into(),
455         Some(mut prev_err) => {
456             if prev_err.offset != ErrorOffset(1) {
457                 let offset = prev_err.offset;
458                 let len = self_.len();
459                 for p in &mut self_[last_parser_having_non_1_offset..(len - 1)] {
460                     prev_err.offset = ErrorOffset(1);
461                     p.add_error(&mut prev_err);
462                 }
463                 prev_err.offset = offset;
464                 self_.last_mut().unwrap().add_error(&mut prev_err);
465                 prev_err.offset = ErrorOffset(0);
466             }
467             prev_err
468         }
469     })
470 }
471 
472 impl<Input, O, P> ChoiceParser<Input> for [P]
473 where
474     Input: Stream,
475     P: Parser<Input, Output = O>,
476 {
477     type Output = O;
478     type PartialState = (usize, P::PartialState);
479 
480     #[inline]
parse_partial( &mut self, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>481     fn parse_partial(
482         &mut self,
483         input: &mut Input,
484         state: &mut Self::PartialState,
485     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
486         slice_parse_mode(self, crate::parser::PartialMode::default(), input, state)
487     }
488 
489     #[inline]
parse_first( &mut self, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>490     fn parse_first(
491         &mut self,
492         input: &mut Input,
493         state: &mut Self::PartialState,
494     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
495         slice_parse_mode(self, crate::parser::FirstMode, input, state)
496     }
497 
498     #[inline]
parse_mode_choice<M>( &mut self, _mode: M, _input: &mut Input, _state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,499     fn parse_mode_choice<M>(
500         &mut self,
501         _mode: M,
502         _input: &mut Input,
503         _state: &mut Self::PartialState,
504     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
505     where
506         M: ParseMode,
507     {
508         unreachable!()
509     }
510 
add_error_choice(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>)511     fn add_error_choice(&mut self, error: &mut Tracked<<Input as StreamOnce>::Error>) {
512         if error.offset != ErrorOffset(0) {
513             for p in self {
514                 error.offset = ErrorOffset(1);
515                 p.add_error(error);
516             }
517         }
518     }
519 }
520 
521 /// Takes a tuple, a slice or an array of parsers and tries to apply them each in order.
522 /// Fails if all the parsers fails or if an applied parser consumes input before failing.
523 ///
524 /// ```
525 /// # extern crate combine;
526 /// # use combine::*;
527 /// # use combine::parser::char::{digit, string};
528 /// # fn main() {
529 /// // `choice` is overloaded on tuples so that different types of parsers can be used
530 /// // (each parser must still have the same input and output types)
531 /// let mut parser = choice((
532 ///     string("Apple").map(|s| s.to_string()),
533 ///     many1(digit()),
534 ///     string("Orange").map(|s| s.to_string()),
535 /// ));
536 /// assert_eq!(parser.parse("1234"), Ok(("1234".to_string(), "")));
537 /// assert_eq!(parser.parse("Orangexx"), Ok(("Orange".to_string(), "xx")));
538 /// assert!(parser.parse("Appl").is_err());
539 /// assert!(parser.parse("Pear").is_err());
540 ///
541 /// // If arrays or slices are used then all parsers must have the same type
542 /// // (`string` in this case)
543 /// let mut parser2 = choice([string("one"), string("two"), string("three")]);
544 /// // Fails as the parser for "two" consumes the first 't' before failing
545 /// assert!(parser2.parse("three").is_err());
546 ///
547 /// // Use 'attempt' to make failing parsers always act as if they have not committed any input
548 /// let mut parser3 = choice([attempt(string("one")), attempt(string("two")), attempt(string("three"))]);
549 /// assert_eq!(parser3.parse("three"), Ok(("three", "")));
550 /// # }
551 /// ```
choice<Input, P>(ps: P) -> Choice<P> where Input: Stream, P: ChoiceParser<Input>,552 pub fn choice<Input, P>(ps: P) -> Choice<P>
553 where
554     Input: Stream,
555     P: ChoiceParser<Input>,
556 {
557     Choice(ps)
558 }
559 
560 #[derive(Copy, Clone)]
561 pub struct Or<P1, P2>(Choice<(P1, P2)>);
562 impl<Input, O, P1, P2> Parser<Input> for Or<P1, P2>
563 where
564     Input: Stream,
565     P1: Parser<Input, Output = O>,
566     P2: Parser<Input, Output = O>,
567 {
568     type Output = O;
569     type PartialState = <Choice<(P1, P2)> as Parser<Input>>::PartialState;
570 
571     parse_mode!(Input);
572     #[inline]
parse_mode_impl<M>( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,573     fn parse_mode_impl<M>(
574         &mut self,
575         mode: M,
576         input: &mut Input,
577         state: &mut Self::PartialState,
578     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
579     where
580         M: ParseMode,
581     {
582         self.0.parse_mode(mode, input, state)
583     }
584 
585     #[inline]
add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>)586     fn add_error(&mut self, errors: &mut Tracked<<Input as StreamOnce>::Error>) {
587         if errors.offset != ErrorOffset(0) {
588             self.0.add_error(errors);
589         }
590     }
591 }
592 
593 /// Equivalent to [`p1.or(p2)`].
594 ///
595 /// If you are looking to chain 3 or more parsers using `or` you may consider using the
596 /// [`choice!`] macro instead, which can be clearer and may result in a faster parser.
597 ///
598 /// ```
599 /// # extern crate combine;
600 /// # use combine::*;
601 /// # use combine::parser::choice::or;
602 /// # use combine::parser::char::{digit, string};
603 /// # fn main() {
604 /// let mut parser = or(
605 ///     string("let"),
606 ///     or(digit().map(|_| "digit"), string("led")),
607 /// );
608 /// assert_eq!(parser.parse("let"), Ok(("let", "")));
609 /// assert_eq!(parser.parse("1"), Ok(("digit", "")));
610 /// assert!(parser.parse("led").is_err());
611 ///
612 /// let mut parser2 = or(string("two"), string("three"));
613 /// // Fails as the parser for "two" consumes the first 't' before failing
614 /// assert!(parser2.parse("three").is_err());
615 ///
616 /// // Use 'attempt' to make failing parsers always act as if they have not committed any input
617 /// let mut parser3 = or(attempt(string("two")), attempt(string("three")));
618 /// assert_eq!(parser3.parse("three"), Ok(("three", "")));
619 /// # }
620 /// ```
621 ///
622 /// [`choice!`]: ../../macro.choice.html
623 /// [`p1.or(p2)`]: ../trait.Parser.html#method.or
or<Input, P1, P2>(p1: P1, p2: P2) -> Or<P1, P2> where Input: Stream, P1: Parser<Input>, P2: Parser<Input, Output = P1::Output>,624 pub fn or<Input, P1, P2>(p1: P1, p2: P2) -> Or<P1, P2>
625 where
626     Input: Stream,
627     P1: Parser<Input>,
628     P2: Parser<Input, Output = P1::Output>,
629 {
630     Or(choice((p1, p2)))
631 }
632 
633 #[derive(Copy, Clone)]
634 pub struct Optional<P>(P);
635 impl<Input, P> Parser<Input> for Optional<P>
636 where
637     Input: Stream,
638     P: Parser<Input>,
639 {
640     type Output = Option<P::Output>;
641     type PartialState = P::PartialState;
642 
643     parse_mode!(Input);
644     #[inline]
parse_mode_impl<M>( &mut self, mode: M, input: &mut Input, state: &mut Self::PartialState, ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> where M: ParseMode,645     fn parse_mode_impl<M>(
646         &mut self,
647         mode: M,
648         input: &mut Input,
649         state: &mut Self::PartialState,
650     ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error>
651     where
652         M: ParseMode,
653     {
654         let before = input.checkpoint();
655         match self.0.parse_mode(mode, input, state) {
656             PeekOk(x) => PeekOk(Some(x)),
657             CommitOk(x) => CommitOk(Some(x)),
658             CommitErr(err) => CommitErr(err),
659             PeekErr(_) => {
660                 ctry!(input.reset(before).committed());
661                 PeekOk(None)
662             }
663         }
664     }
665 
666     forward_parser!(Input, add_error parser_count, 0);
667 }
668 
669 /// Parses `parser` and outputs `Some(value)` if it succeeds, `None` if it fails without
670 /// consuming any input. Fails if `parser` fails after having committed some input.
671 ///
672 /// ```
673 /// # extern crate combine;
674 /// # use combine::*;
675 /// # use combine::parser::char::string;
676 /// # fn main() {
677 /// let mut parser = optional(string("hello"));
678 /// assert_eq!(parser.parse("hello"), Ok((Some("hello"), "")));
679 /// assert_eq!(parser.parse("world"), Ok((None, "world")));
680 /// assert!(parser.parse("heya").is_err());
681 /// # }
682 /// ```
optional<Input, P>(parser: P) -> Optional<P> where Input: Stream, P: Parser<Input>,683 pub fn optional<Input, P>(parser: P) -> Optional<P>
684 where
685     Input: Stream,
686     P: Parser<Input>,
687 {
688     Optional(parser)
689 }
690 
691 #[macro_export]
692 #[doc(hidden)]
693 macro_rules! parse_mode_dispatch {
694     () => {
695         fn parse_partial(
696             &mut self,
697             input: &mut Input,
698             state: &mut Self::PartialState,
699         ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
700             self.parse_mode_dispatch($crate::parser::PartialMode::default(), input, state)
701         }
702 
703         fn parse_first(
704             &mut self,
705             input: &mut Input,
706             state: &mut Self::PartialState,
707         ) -> ParseResult<Self::Output, <Input as StreamOnce>::Error> {
708             self.parse_mode_dispatch($crate::parser::FirstMode, input, state)
709         }
710     };
711 }
712 
713 #[macro_export]
714 #[doc(hidden)]
715 macro_rules! dispatch_parser_impl {
716     ($parser_name: ident [$first_ident: ident $($id: ident)*] [$($collected_idents: ident)*] $expr: expr, $($rest: expr,)*) => {
717         $crate::dispatch_parser_impl!{ $parser_name [ $($id)* ] [$($collected_idents)* $first_ident] $($rest,)*}
718     };
719     ($parser_name: ident [$($id: ident)*] [$($collected_idents: ident)*]) => {
720         $crate::dispatch_parser_impl!{ $parser_name; $($collected_idents)* }
721     };
722 
723     ($parser_name: ident; $($id: ident)*) => {
724         pub enum $parser_name<$($id),*> {
725             $(
726                 $id($id),
727             )*
728         }
729 
730         #[allow(non_snake_case)]
731         impl<Input, Output, $($id),*> $crate::Parser<Input> for $parser_name<$($id),*>
732             where
733                 $( $id: $crate::Parser<Input, Output = Output>, )*
734                 Input: $crate::Stream,
735         {
736             type Output = Output;
737             type PartialState = Option<$parser_name<$($id::PartialState),*>>;
738 
739             $crate::parse_mode!(Input);
740             fn parse_mode<Mode>(
741                 &mut self,
742                 mode: Mode,
743                 input: &mut Input,
744                 state: &mut Self::PartialState,
745             ) -> $crate::error::ParseResult<Self::Output, <Input as $crate::StreamOnce>::Error>
746             where
747                 Mode: $crate::parser::ParseMode,
748             {
749                 match self {
750                     $(
751                     $parser_name::$id($id) => {
752                         let state = match state {
753                             Some($parser_name::$id(s)) => s,
754                             _ => {
755                                 *state = Some($parser_name::$id(Default::default()));
756                                 match state {
757                                     Some($parser_name::$id(s)) => s,
758                                     _ => unreachable!(),
759                                 }
760                             }
761                         };
762                         $id.parse_mode(mode, input, state)
763                     }
764                     )*
765                 }
766             }
767 
768             fn add_error(&mut self, error: &mut $crate::error::Tracked<<Input as $crate::StreamOnce>::Error>) {
769                 match self {
770                     $(
771                     $parser_name::$id($id) => $id.add_error(error),
772                     )*
773                 }
774             }
775         }
776     }
777 }
778 
779 #[macro_export]
780 #[doc(hidden)]
781 macro_rules! dispatch_inner {
782     ($expr_ident: ident [$first_ident: ident $($id: ident)*] [$($collected: tt)*] $($pat: pat)|+ $(if $pred:expr)? => $expr: expr, $($rest_alt: tt)*) => {
783         $crate::dispatch_inner!{ $expr_ident [ $($id)* ] [$($collected)* $first_ident $($pat)|+ $(if $pred)? => $expr,] $($rest_alt)*}
784     };
785     ($expr_ident: ident [$($id: ident)*] [$($collected: tt)*]) => {
786         $crate::dispatch_inner!{ $expr_ident $($collected)* }
787     };
788     ($expr_ident: ident [$($ident_tt: tt)*]) => {
789         unreachable!()
790     };
791     ($expr_ident: ident $( $ident: ident $($pat: pat)|+ $(if $pred:expr)? => $expr: expr,)+ ) => {
792         match $expr_ident {
793             $(
794                 $($pat)|+ $(if $pred)? => Dispatch::$ident(check_parser($expr)),
795             )+
796         }
797     }
798 }
799 
800 /// `dispatch!` allows a parser to be constructed depending on earlier input, without forcing each
801 /// branch to have the same type of parser
802 ///
803 /// ```
804 /// use combine::{dispatch, any, token, satisfy, EasyParser, Parser};
805 ///
806 /// let mut parser = any().then(|e| {
807 ///     dispatch!(e;
808 ///         'a' => token('a'),
809 ///         'b' => satisfy(|b| b == 'b'),
810 ///         t if t == 'c' => any(),
811 ///         _ => token('d')
812 ///     )
813 /// });
814 /// assert_eq!(parser.easy_parse("aa"), Ok(('a', "")));
815 /// assert_eq!(parser.easy_parse("cc"), Ok(('c', "")));
816 /// assert_eq!(parser.easy_parse("cd"), Ok(('d', "")));
817 /// assert!(parser.easy_parse("ab").is_err());
818 /// ```
819 #[macro_export]
820 macro_rules! dispatch {
821     ($match_expr: expr; $( $($pat: pat)|+ $(if $pred:expr)? => $expr: expr ),+ $(,)? ) => {
822         {
823             $crate::dispatch_parser_impl!{ Dispatch [A B C D E F G H I J K L M N O P Q R S T U V X Y Z] [] $($expr,)+ }
824 
825             fn check_parser<Input, P>(p: P) -> P where P: $crate::Parser<Input>, Input: $crate::Stream { p }
826 
827             let e = $match_expr;
828             let parser = $crate::dispatch_inner!(e [A B C D E F G H I J K L M N O P Q R S T U V X Y Z] []
829                 $(
830                     $($pat)|+ $(if $pred)? => $expr,
831                 )*
832             );
833             parser
834         }
835     }
836 }
837 
838 #[cfg(all(feature = "std", test))]
839 mod tests {
840 
841     use crate::parser::{token::any, EasyParser};
842 
843     use super::*;
844 
845     #[test]
choice_single_parser()846     fn choice_single_parser() {
847         assert!(choice((any(),),).easy_parse("a").is_ok());
848     }
849 }
850