nom_errors/
lib.rs

1#![feature(never_type)]
2
3#![deny(warnings)]
4#![allow(clippy::too_many_arguments)]
5
6use nom::{self, IResult, InputLength};
7use nom::error::ParseError;
8use paste::paste;
9
10#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
11pub enum NomErr<E, F> {
12    Error(E),
13    Failure(F),
14}
15
16impl<E, F> NomErr<E, F> {
17    pub fn map_err<X>(self, f: impl FnOnce(E) -> X) -> NomErr<X, F> {
18        match self {
19            NomErr::Error(e) => NomErr::Error(f(e)),
20            NomErr::Failure(e) => NomErr::Failure(e),
21        }
22    }
23
24    pub fn map_fail<X>(self, f: impl FnOnce(F) -> X) -> NomErr<E, X> {
25        match self {
26            NomErr::Error(e) => NomErr::Error(e),
27            NomErr::Failure(e) => NomErr::Failure(f(e)),
28        }
29    }
30}
31
32impl<F> NomErr<!, F> {
33    pub fn any_err<E>(self) -> NomErr<E, F> {
34        self.map_err(|x| x)
35    }
36}
37
38impl<E> NomErr<E, !> {
39    pub fn any_fail<F>(self) -> NomErr<E, F> {
40        self.map_fail(|x| x)
41    }
42}
43
44impl<E> NomErr<E, E> {
45    pub fn fail(self) -> NomErr<!, E> {
46        match self {
47            NomErr::Error(e) => NomErr::Failure(e),
48            NomErr::Failure(e) => NomErr::Failure(e),
49        }
50    }
51}
52
53impl<I, E, F> ParseError<I> for NomErr<E, F> {
54    fn from_error_kind(_input: I, _kind: nom::error::ErrorKind) -> Self { panic!() }
55
56    fn append(_input: I, _kind: nom::error::ErrorKind, _other: Self) -> Self { panic!() }
57
58    fn or(self, _other: Self) -> Self { panic!() }
59
60    fn from_char(_input: I, _: char) -> Self { panic!() }
61}
62
63pub type NomRes<I, O, E, F> = IResult<I, O, NomErr<E, F>>;
64
65pub fn parser_from_result<I, O, E, F>(r: Result<(I, O), NomErr<E, F>>) -> NomRes<I, O, E, F> {
66    match r {
67        Ok((i, o)) => Ok((i, o)),
68        Err(NomErr::Error(e)) => Err(nom::Err::Error(NomErr::Error(e))),
69        Err(NomErr::Failure(f)) => Err(nom::Err::Failure(NomErr::Failure(f))),
70    }
71}
72
73pub fn result_from_parser<I, O, E, F>(r: NomRes<I, O, E, F>) -> Result<(I, O), NomErr<E, F>> {
74    match r {
75        Ok((i, o)) => Ok((i, o)),
76        Err(nom::Err::Error(NomErr::Error(e))) => Err(NomErr::Error(e)),
77        Err(nom::Err::Failure(NomErr::Failure(e))) => Err(NomErr::Failure(e)),
78        _ => panic!()
79    }
80}
81
82pub fn map_err<I: Clone, O, E, F, X>(
83    mut parser: impl FnMut(I) -> NomRes<I, O, E, F>,
84    mut f: impl FnMut(E, I) -> X
85) -> impl FnMut(I) -> NomRes<I, O, X, F> {
86    move |input: I| {
87        parser_from_result(result_from_parser(parser(input.clone())).map_err(|e| e.map_err(|e| f(e, input))))
88    }
89}
90
91pub fn any_err<I: Clone, O, F, X>(
92    mut parser: impl FnMut(I) -> NomRes<I, O, !, F>,
93) -> impl FnMut(I) -> NomRes<I, O, X, F> {
94    move |input: I| parser_from_result(result_from_parser(parser(input)).map_err(|e| e.any_err()))
95}
96
97pub fn uni_err_no_fail<I, O>(
98    mut parser: impl FnMut(I) -> IResult<I, O, ()>
99) -> impl FnMut(I) -> NomRes<I, O, (), !> {
100    move |input: I| parser_from_result(match parser(input) {
101        Ok((i, o)) => Ok((i, o)),
102        Err(nom::Err::Error(())) => Err(NomErr::Error(())),
103        _ => panic!(),
104    })
105}
106
107pub fn seq_2<I, O1, O2, E, F>(
108    mut a: impl FnMut(I) -> NomRes<I, O1, E, F>,
109    mut b: impl FnMut(I) -> NomRes<I, O2, E, F>,
110) -> impl FnMut(I) -> NomRes<I, (O1, O2), E, F> {
111    move |input: I| parser_from_result(match result_from_parser(a(input)) {
112        Err(e) => Err(e),
113        Ok((input, a)) => result_from_parser(b(input)).map(|(i, b)| (i, (a, b)))
114    })
115}
116
117macro_rules! seq_n {
118    (
119        $n:literal; $m:literal: $($i:literal),+
120    ) => {
121        paste! {
122            pub fn [< seq_ $n >] <I, $( [< O $i >] , )+ [< O $n >] , E, F>(
123                $(
124                    [< parser_ $i >] : impl FnMut(I) -> NomRes<I, [< O $i >] , E, F>,
125                )+
126                [< parser_ $n >] : impl FnMut(I) -> NomRes<I, [< O $n >] , E, F>,
127            ) -> impl FnMut(I) -> NomRes<I, ($( [< O $i >], )+ [< O $n >] ), E, F> {
128                map(
129                    seq_2( [< seq_ $m >] ($( [< parser_ $i >] ),+), [< parser_ $n >] ),
130                    |(($( [< r $i >] ),+), [< r $n >] )| ($( [< r $i >] ,)+ [< r $n >] )
131                )
132            }
133        }
134    };
135}
136
137seq_n!(3; 2: 1, 2);
138seq_n!(4; 3: 1, 2, 3);
139seq_n!(5; 4: 1, 2, 3, 4);
140seq_n!(6; 5: 1, 2, 3, 4, 5);
141seq_n!(7; 6: 1, 2, 3, 4, 5, 6);
142seq_n!(8; 7: 1, 2, 3, 4, 5, 6, 7);
143seq_n!(9; 8: 1, 2, 3, 4, 5, 6, 7, 8);
144seq_n!(10; 9: 1, 2, 3, 4, 5, 6, 7, 8, 9);
145seq_n!(11; 10: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
146seq_n!(12; 11: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
147seq_n!(13; 12: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
148seq_n!(14; 13: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
149seq_n!(15; 14: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
150
151pub fn alt_2<I: Clone, O, E, F, X1>(
152    mut parser_1: impl FnMut(I) -> NomRes<I, O, X1, F>,
153    mut parser: impl FnMut(I) -> NomRes<I, O, E, F>,
154) -> impl FnMut(I) -> NomRes<I, O, E, F> {
155    move |input: I| parser_from_result(match result_from_parser(parser_1(input.clone())) {
156        Ok(r) => Ok(r),
157        Err(NomErr::Failure(f)) => Err(NomErr::Failure(f)),
158        Err(NomErr::Error(_)) => result_from_parser(parser(input)),
159    })
160}
161
162macro_rules! alt_n {
163    (
164        $n:literal; $m:literal: $($i:literal),+
165    ) => {
166        paste! {
167            pub fn [< alt_ $n >] <I: Clone, O, E, F, $( [< X $i >]),+>(
168                $(
169                    [< parser_ $i >] : impl FnMut(I) -> NomRes<I, O, [< X $i >], F>,
170                )+
171                parser: impl FnMut(I) -> NomRes<I, O, E, F>,
172            ) -> impl FnMut(I) -> NomRes<I, O, E, F> {
173                alt_2( [< alt_ $m >] ($( [< parser_ $i >] ),+), parser)
174            }
175        }
176    };
177}
178
179alt_n!(3; 2: 1, 2);
180alt_n!(4; 3: 1, 2, 3);
181alt_n!(5; 4: 1, 2, 3, 4);
182alt_n!(6; 5: 1, 2, 3, 4, 5);
183alt_n!(7; 6: 1, 2, 3, 4, 5, 6);
184alt_n!(8; 7: 1, 2, 3, 4, 5, 6, 7);
185alt_n!(9; 8: 1, 2, 3, 4, 5, 6, 7, 8);
186alt_n!(10; 9: 1, 2, 3, 4, 5, 6, 7, 8, 9);
187alt_n!(11; 10: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
188alt_n!(12; 11: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
189alt_n!(13; 12: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
190alt_n!(14; 13: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
191alt_n!(15; 14: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
192
193pub fn many0<I: Clone + InputLength, O, E, F>(
194    mut parser: impl FnMut(I) -> NomRes<I, O, E, F>
195) -> impl FnMut(I) -> NomRes<I, Vec<O>, !, F> {
196    move |mut input: I| parser_from_result({
197        let mut r = Vec::new();
198        loop {
199            if input.input_len() == 0 { break Ok(()); }
200            match result_from_parser(parser(input.clone())) {
201                Ok((i, o)) => {
202                    assert_ne!(i.input_len(), input.input_len(), "invalid many0 parser");
203                    input = i;
204                    r.push(o);
205                },
206                Err(NomErr::Failure(f)) => break Err(NomErr::Failure(f)),
207                Err(NomErr::Error(_)) => break Ok(()),
208            }
209        }.map(|()| (input, r))
210    })
211}
212
213pub fn map<I, O, E, F, X>(
214    mut parser: impl FnMut(I) -> NomRes<I, O, E, F>,
215    mut f: impl FnMut(O) -> X
216) -> impl FnMut(I) -> NomRes<I, X, E, F> {
217    move |input: I| parser_from_result(result_from_parser(parser(input)).map(|(i, r)| (i, f(r))))
218}
219
220pub fn map_res<I, O, E, F, X>(
221    mut parser: impl FnMut(I) -> NomRes<I, O, E, F>,
222    mut f: impl FnMut(O) -> Result<X, E>
223) -> impl FnMut(I) -> NomRes<I, X, E, F> {
224    move |input: I| parser_from_result(result_from_parser(parser(input)).and_then(|(i, r)|
225        f(r).map_err(NomErr::Error).map(|r| (i, r))
226    ))
227}
228
229pub fn all_consuming<I: InputLength, O, E, F>(
230    mut parser: impl FnMut(I) -> NomRes<I, O, E, F>,
231    mut f: impl FnMut(I) -> NomErr<E, F>,
232) -> impl FnMut(I) -> NomRes<I, O, E, F> {
233    move |input: I| parser_from_result(result_from_parser(parser(input)).and_then(|(i, r)|
234        if i.input_len() == 0 { Ok((i, r)) } else { Err(f(i)) }
235    ))
236}
237
238pub fn flat_map<I, O1, O2, E, F, P: FnMut(I) -> NomRes<I, O2, E, F>>(
239    mut parser: impl FnMut(I) -> NomRes<I, O1, E, F>,
240    mut f: impl FnMut(O1) -> P,
241) -> impl FnMut(I) -> NomRes<I, O2, E, F> {
242    move |input: I| parser_from_result(match result_from_parser(parser(input)) {
243        Err(e) => Err(e),
244        Ok((i, r1)) => result_from_parser(f(r1)(i))
245    })
246}
247
248pub fn count<I: Clone + PartialEq, O, E, F>(
249    mut parser: impl FnMut(I) -> NomRes<I, O, E, F>,
250    count: usize
251) -> impl FnMut(I) -> NomRes<I, Vec<O>, E, F> {
252    move |mut input: I| parser_from_result((|| {
253        let mut r = Vec::new();
254        for _ in 0 .. count {
255            let (i, o) = result_from_parser(parser(input.clone()))?;
256            input = i;
257            r.push(o);
258        }
259        Ok((input, r))
260    })())
261}
262
263pub mod bytes {
264    use super::*;
265    use nom::{Compare, InputIter, InputLength, InputTake, Slice};
266    use std::ops::RangeFrom;
267
268    pub fn le_u8<I: Slice<RangeFrom<usize>> + InputIter<Item=u8> + InputLength>() -> impl FnMut(I) -> NomRes<I, u8, (), !> {
269        uni_err_no_fail(nom::number::complete::le_u8)
270    }
271
272    pub fn le_u16<I: Slice<RangeFrom<usize>> + InputIter<Item=u8> + InputLength>() -> impl FnMut(I) -> NomRes<I, u16, (), !> {
273        uni_err_no_fail(nom::number::complete::le_u16)
274    }
275
276    pub fn le_u32<I: Slice<RangeFrom<usize>> + InputIter<Item=u8> + InputLength>() -> impl FnMut(I) -> NomRes<I, u32, (), !> {
277        uni_err_no_fail(nom::number::complete::le_u32)
278    }
279
280    pub fn le_i8<I: Slice<RangeFrom<usize>> + InputIter<Item=u8> + InputLength>() -> impl FnMut(I) -> NomRes<I, i8, (), !> {
281        uni_err_no_fail(nom::number::complete::le_i8)
282    }
283
284    pub fn le_i16<I: Slice<RangeFrom<usize>> + InputIter<Item=u8> + InputLength>() -> impl FnMut(I) -> NomRes<I, i16, (), !> {
285        uni_err_no_fail(nom::number::complete::le_i16)
286    }
287
288    pub fn le_i32<I: Slice<RangeFrom<usize>> + InputIter<Item=u8> + InputLength>() -> impl FnMut(I) -> NomRes<I, i32, (), !> {
289        uni_err_no_fail(nom::number::complete::le_i32)
290    }
291
292    pub fn tag<T: Clone + InputLength, I: InputTake + Compare<T>>(
293        tag: T
294    ) -> impl FnMut(I) -> NomRes<I, I, (), !> {
295        uni_err_no_fail(nom::bytes::complete::tag(tag))
296    }
297
298    pub fn take<I: InputIter + InputTake>(
299        count: usize
300    ) -> impl FnMut(I) -> NomRes<I, I, (), !> {
301        uni_err_no_fail(nom::bytes::complete::take(count))
302    }
303
304    pub fn take_all<I: InputLength + InputTake>() -> impl FnMut(I) -> NomRes<I, I, !, !> {
305        move |input: I| {
306            let input_len = input.input_len();
307            Ok(input.take_split(input_len))
308        }
309    }
310}