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
42macro_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