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
use nom::{error::ErrorKind, IResult};

#[macro_export]
macro_rules! fields {
    (from $input:ident { $($name:ident : $combinator:expr),+ $(,)* } do $body:expr) => {
        |$input| {
            let ($input, ($($name),+)) = nom::sequence::tuple(($($combinator),+))($input)?;
            $body
        }
    };

    ({ $($name:ident : $combinator:expr),+ $(,)* } chain $next:expr) => {
        fields!(from i { $($name: $combinator,)+ } do $next(i))
    };

    ({ $($name:ident : $combinator:expr),+ $(,)* } map $body:expr) => {
        fields!(from i { $($name: $combinator,)+ } do {
            Ok((i, $body))
        })
    };

    ($struct:ident { $($name:ident : $combinator:expr),+ $(,)* }) => {
        fields!({ $($name: $combinator,)+ } map
            $struct { $($name,)+ }
        )
    };
}

/// Result of a parse operation
///
/// Used internally when parsing, for example, the end of central directory record.
pub type Result<'a, T> = IResult<&'a [u8], T, Error<'a>>;

/// Parsing error, see [Error].
pub type Error<'a> = (&'a [u8], ErrorKind);