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::success;
18/// # use winnow::combinator::fail;
19///
20/// fn escaped(input: &str) -> IResult<&str, char> {
21/// preceded('\\', escape_seq_char).parse_next(input)
22/// }
23///
24/// fn escape_seq_char(input: &str) -> IResult<&str, char> {
25/// dispatch! {any;
26/// 'b' => success('\u{8}'),
27/// 'f' => success('\u{c}'),
28/// 'n' => success('\n'),
29/// 'r' => success('\r'),
30/// 't' => success('\t'),
31/// '\\' => success('\\'),
32/// '"' => success('"'),
33/// _ => fail::<_, char, _>,
34/// }
35/// .parse_next(input)
36/// }
37///
38/// assert_eq!(escaped.parse_next("\\nHello"), Ok(("Hello", '\n')));
39/// ```
40#[macro_export]
41macro_rules! dispatch {
42 ($match_parser: expr; $( $pat:pat $(if $pred:expr)? => $expr: expr ),+ $(,)? ) => {
43 $crate::trace::trace("dispatch", move |i|
44 {
45 use $crate::Parser;
46 let (i, initial) = $match_parser.parse_next(i)?;
47 match initial {
48 $(
49 $pat $(if $pred)? => $expr.parse_next(i),
50 )*
51 }
52 })
53 }
54}
55
56macro_rules! succ (
57 (0, $submac:ident ! ($($rest:tt)*)) => ($submac!(1, $($rest)*));
58 (1, $submac:ident ! ($($rest:tt)*)) => ($submac!(2, $($rest)*));
59 (2, $submac:ident ! ($($rest:tt)*)) => ($submac!(3, $($rest)*));
60 (3, $submac:ident ! ($($rest:tt)*)) => ($submac!(4, $($rest)*));
61 (4, $submac:ident ! ($($rest:tt)*)) => ($submac!(5, $($rest)*));
62 (5, $submac:ident ! ($($rest:tt)*)) => ($submac!(6, $($rest)*));
63 (6, $submac:ident ! ($($rest:tt)*)) => ($submac!(7, $($rest)*));
64 (7, $submac:ident ! ($($rest:tt)*)) => ($submac!(8, $($rest)*));
65 (8, $submac:ident ! ($($rest:tt)*)) => ($submac!(9, $($rest)*));
66 (9, $submac:ident ! ($($rest:tt)*)) => ($submac!(10, $($rest)*));
67 (10, $submac:ident ! ($($rest:tt)*)) => ($submac!(11, $($rest)*));
68 (11, $submac:ident ! ($($rest:tt)*)) => ($submac!(12, $($rest)*));
69 (12, $submac:ident ! ($($rest:tt)*)) => ($submac!(13, $($rest)*));
70 (13, $submac:ident ! ($($rest:tt)*)) => ($submac!(14, $($rest)*));
71 (14, $submac:ident ! ($($rest:tt)*)) => ($submac!(15, $($rest)*));
72 (15, $submac:ident ! ($($rest:tt)*)) => ($submac!(16, $($rest)*));
73 (16, $submac:ident ! ($($rest:tt)*)) => ($submac!(17, $($rest)*));
74 (17, $submac:ident ! ($($rest:tt)*)) => ($submac!(18, $($rest)*));
75 (18, $submac:ident ! ($($rest:tt)*)) => ($submac!(19, $($rest)*));
76 (19, $submac:ident ! ($($rest:tt)*)) => ($submac!(20, $($rest)*));
77 (20, $submac:ident ! ($($rest:tt)*)) => ($submac!(21, $($rest)*));
78);
79