1 /// `match` for parsers
2 ///
3 /// When parsers have unique prefixes to test for, this offers better performance over
4 /// [`alt`][crate::combinator::alt] though it might be at the cost of duplicating parts of your grammar
5 /// if you needed to [`peek`][crate::combinator::peek].
6 ///
7 /// For tight control over the error in a catch-all case, use [`fail`][crate::combinator::fail].
8 ///
9 /// # Example
10 ///
11 /// ```rust
12 /// use winnow::prelude::*;
13 /// use winnow::combinator::dispatch;
14 /// # use winnow::token::any;
15 /// # use winnow::combinator::peek;
16 /// # use winnow::combinator::preceded;
17 /// # use winnow::combinator::empty;
18 /// # use winnow::combinator::fail;
19 ///
20 /// fn escaped(input: &mut &str) -> PResult<char> {
21 ///     preceded('\\', escape_seq_char).parse_next(input)
22 /// }
23 ///
24 /// fn escape_seq_char(input: &mut &str) -> PResult<char> {
25 ///     dispatch! {any;
26 ///         'b' => empty.value('\u{8}'),
27 ///         'f' => empty.value('\u{c}'),
28 ///         'n' => empty.value('\n'),
29 ///         'r' => empty.value('\r'),
30 ///         't' => empty.value('\t'),
31 ///         '\\' => empty.value('\\'),
32 ///         '"' => empty.value('"'),
33 ///         _ => fail::<_, char, _>,
34 ///     }
35 ///     .parse_next(input)
36 /// }
37 ///
38 /// assert_eq!(escaped.parse_peek("\\nHello"), Ok(("Hello", '\n')));
39 /// ```
40 #[macro_export]
41 #[doc(hidden)] // forced to be visible in intended location
42 macro_rules! dispatch {
43     ($match_parser: expr; $( $pat:pat $(if $pred:expr)? => $expr: expr ),+ $(,)? ) => {
44         $crate::combinator::trace("dispatch", move |i: &mut _|
45         {
46             use $crate::Parser;
47             let initial = $match_parser.parse_next(i)?;
48             match initial {
49                 $(
50                     $pat $(if $pred)? => $expr.parse_next(i),
51                 )*
52             }
53         })
54     }
55 }
56