1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use crate::parser::then::Then2;
use crate::parser::{ParseResult, Parser};

/// Use a second trait to force usage of the [`one_of`] method, preventing tuples from being used as
/// parsers directly, which could be confusing.
pub trait ParserList {
    type Output<'i>;
    fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>>;
}

macro_rules! parserlist_impl {
    ($($l:ident: $n:tt),+) => {
        impl<A: Parser, $($l: for<'i> Parser<Output<'i> = A::Output<'i>>),+> ParserList for (A, $($l,)*) {
            type Output<'i> = A::Output<'i>;

            #[inline(always)]
            fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
                let mut err = match self.0.parse(input) {
                    Ok(v) => return Ok(v),
                    Err(err) => err,
                };

                $(match self.$n.parse(input) {
                    Ok(v) => return Ok(v),
                    Err(this_err) => {
                        if this_err.1.len() < err.1.len() {
                            err = this_err;
                        }
                    }
                })+

                Err(err)
            }
        }
    };
}

parserlist_impl! {B: 1}
parserlist_impl! {B: 1, C: 2}
parserlist_impl! {B: 1, C: 2, D: 3}
parserlist_impl! {B: 1, C: 2, D: 3, E: 4}
parserlist_impl! {B: 1, C: 2, D: 3, E: 4, F: 5}
parserlist_impl! {B: 1, C: 2, D: 3, E: 4, F: 5, G: 6}
parserlist_impl! {B: 1, C: 2, D: 3, E: 4, F: 5, G: 6, H: 7}
parserlist_impl! {B: 1, C: 2, D: 3, E: 4, F: 5, G: 6, H: 7, I: 8}
parserlist_impl! {B: 1, C: 2, D: 3, E: 4, F: 5, G: 6, H: 7, I: 8, J: 9}
parserlist_impl! {B: 1, C: 2, D: 3, E: 4, F: 5, G: 6, H: 7, I: 8, J: 9, K: 10}
parserlist_impl! {B: 1, C: 2, D: 3, E: 4, F: 5, G: 6, H: 7, I: 8, J: 9, K: 10, L: 11}

#[derive(Copy, Clone)]
pub struct OneOf<L> {
    list: L,
}
impl<L: ParserList> Parser for OneOf<L> {
    type Output<'i> = L::Output<'i>;
    type Then<T: Parser> = Then2<Self, T>;

    #[inline]
    fn parse<'i>(&self, input: &'i [u8]) -> ParseResult<'i, Self::Output<'i>> {
        self.list.parse(input)
    }
}

/// Attempt to parse using a list of parsers.
///
/// Similar to [`Parser::or`], each parser will be tried in order until one succeeds. If no parsers
/// succeed, the error from the parser furthest into the input is returned.
///
/// Prefer [`parser::literal_map`](super::literal_map) if all the parsers are string literals.
///
/// # Examples
/// ```
/// # use utils::input::InputError;
/// # use utils::parser::{self, ParseError, Parser};
/// #[derive(Debug, PartialEq)]
/// enum Value {
///     Unsigned8(u8),
///     Unsigned32(u32),
///     Signed8(i8),
///     Signed32(i32),
/// }
///
/// let parser = parser::one_of((
///     parser::u8().map(Value::Unsigned8),
///     parser::u32().map(Value::Unsigned32),
///     parser::i8().map(Value::Signed8),
///     parser::i32().map(Value::Signed32),
/// ));
///
/// assert_eq!(
///     parser.parse_complete("31").unwrap(),
///     Value::Unsigned8(31),
/// );
/// assert_eq!(
///     parser.parse_complete("4294967295").unwrap(),
///     Value::Unsigned32(4294967295),
/// );
/// assert_eq!(
///     parser.parse_complete("-1").unwrap(),
///     Value::Signed8(-1)
/// );
/// assert_eq!(
///     parser.parse_complete("-2147483648").unwrap(),
///     Value::Signed32(-2147483648)
/// );
///
/// assert_eq!(
///     parser.parse(b"not a number").unwrap_err().0,
///     ParseError::Expected("unsigned integer")
/// );
/// assert_eq!(
///     parser.parse(b"-4294967295").unwrap_err().0,
///     ParseError::NumberTooSmall(-2147483648)
/// );
/// ```
pub fn one_of<L: ParserList>(options: L) -> OneOf<L> {
    OneOf { list: options }
}