Coverage Report

Created: 2025-11-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/nom-derive-0.10.1/src/traits.rs
Line
Count
Source
1
use nom::bytes::streaming::take;
2
use nom::combinator::{complete, map_res, opt};
3
use nom::error::{Error, FromExternalError, ParseError};
4
use nom::multi::{many0, many_m_n};
5
use nom::number::streaming::*;
6
use nom::sequence::pair;
7
use nom::*;
8
use std::convert::TryFrom;
9
use std::ops::RangeFrom;
10
11
pub use nom::{InputLength, Slice};
12
13
pub trait InputSlice:
14
    Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength + InputTake
15
{
16
}
17
impl<'a> InputSlice for &'a [u8] {}
18
19
/// Common trait for all parsers in nom-derive
20
///
21
/// This trait is used to provide parser implementations, usually as generic as possible for the
22
/// error type. Implementations are provided for common and primitive types.
23
/// The only required method is `parse`, but it is advised to implement the `parse_be` and `parse_le`
24
/// methods. Derived code will call one of these methods, depending on the field endianness.
25
///
26
/// # Example
27
///
28
/// A possible implementation for the type `u32` is:
29
/// ```rust,ignore
30
/// impl<I, E> Parse<I, E> for u32
31
/// where
32
///     E: ParseError<I>,
33
///     I: InputSlice,
34
/// {
35
///     fn parse(i: I) -> IResult<I, Self, E> { be_u32(i) } // default to big-endian
36
///     fn parse_be(i: I) -> IResult<I, Self, E> { be_u32(i) }
37
///     fn parse_le(i: I) -> IResult<I, Self, E> { le_u32(i) }
38
/// }
39
/// ```
40
///
41
/// # Generic type parameters and input
42
///
43
/// Note: `I` is a generic type that is mostly equivalent to `&'a [u8]`. It is used to
44
/// "hide" the lifetime of the input slice `&'a [u8]` and simplify traits implementation
45
/// and generation of derived code.
46
///
47
/// It is possible to implement the `Parse` trait only for `&[u8]` if the
48
/// implementation contains non-generic functions.
49
///
50
/// For example, the implementation for `String` is:
51
/// ```rust,ignore
52
/// impl<'a, E> Parse<&'a [u8], E> for String
53
/// where
54
///     E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], std::str::Utf8Error>,
55
/// {
56
///     fn parse(i: &'a [u8]) -> IResult<&'a [u8], Self, E> {
57
///         let (rem, sz) = <u32>::parse(i)?;
58
///         let (rem, s) = map_res(take(sz as usize), std::str::from_utf8)(rem)?;
59
///         Ok((rem, s.to_owned()))
60
///     }
61
/// }
62
/// ```
63
///
64
/// # Implementing primitives or specific types
65
///
66
/// To implement an existing type differently, or a type where implementation was not provided, a
67
/// common way is to use a newtype pattern:
68
///
69
/// ```rust
70
/// use nom_derive::{Parse, nom};
71
///
72
/// use nom::IResult;
73
/// use nom::bytes::complete::take;
74
/// use nom::combinator::map_res;
75
/// use nom::error::{Error, FromExternalError, ParseError};
76
///
77
/// # #[derive(Debug, PartialEq)]
78
/// pub struct MyString(pub String);
79
/// impl<'a, E> Parse<&'a [u8], E> for MyString
80
/// where
81
///     E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], std::str::Utf8Error>,
82
/// {
83
///     fn parse(i: &'a [u8]) -> IResult<&'a [u8], Self, E> {
84
///         let (rem, sz) = <u32>::parse(i)?;
85
///         let (rem, s) = map_res(take(sz as usize), std::str::from_utf8)(rem)?;
86
///         Ok((rem, MyString(s.to_owned())))
87
///     }
88
/// }
89
///
90
/// # let input = b"\x00\x00\x00\x04test";
91
/// // error type cannot be inferred by compiler and must be explicit
92
/// let res: IResult<_, _, Error<_>> = MyString::parse(input);
93
/// # assert_eq!(res, Ok((&input[8..], MyString(String::from("test")))));
94
/// ```
95
pub trait Parse<I, E = Error<I>>
96
where
97
    I: InputSlice,
98
    E: ParseError<I>,
99
    Self: Sized,
100
{
101
    /// Parse input, not knowing the endianness
102
    ///
103
    /// Usually, this means choosing between big and little-endian.
104
    /// Default implementations for common types are big-endian.
105
    fn parse(i: I) -> IResult<I, Self, E>;
106
107
    /// Parse input as Big-Endian
108
    fn parse_be(i: I) -> IResult<I, Self, E> {
109
        Self::parse(i)
110
    }
111
112
    /// Parse input as Little-Endian
113
    fn parse_le(i: I) -> IResult<I, Self, E> {
114
        Self::parse(i)
115
    }
116
}
117
118
macro_rules! impl_primitive_type {
119
    ( $ty:ty, $be_fn: ident, $le_fn: ident ) => {
120
        impl<I, E> Parse<I, E> for $ty
121
        where
122
            E: ParseError<I>,
123
            I: InputSlice,
124
        {
125
            fn parse(i: I) -> IResult<I, Self, E> {
126
                Self::parse_be(i)
127
            }
128
16.5M
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
16.5M
                $be_fn(i)
130
16.5M
            }
<i8 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
96.1k
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
96.1k
                $be_fn(i)
130
96.1k
            }
<u8 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
48.1k
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
48.1k
                $be_fn(i)
130
48.1k
            }
<u16 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
8.13M
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
8.13M
                $be_fn(i)
130
8.13M
            }
<u32 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
149k
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
149k
                $be_fn(i)
130
149k
            }
<u64 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
191k
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
191k
                $be_fn(i)
130
191k
            }
<u8 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
560k
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
560k
                $be_fn(i)
130
560k
            }
<u16 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
825k
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
825k
                $be_fn(i)
130
825k
            }
<i8 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
86.5k
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
86.5k
                $be_fn(i)
130
86.5k
            }
<u8 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
43.3k
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
43.3k
                $be_fn(i)
130
43.3k
            }
<u16 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
3.90M
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
3.90M
                $be_fn(i)
130
3.90M
            }
<u32 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
133k
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
133k
                $be_fn(i)
130
133k
            }
<u64 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
172k
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
172k
                $be_fn(i)
130
172k
            }
<u8 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
1.61M
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
1.61M
                $be_fn(i)
130
1.61M
            }
<u16 as nom_derive::traits::Parse<&[u8]>>::parse_be
Line
Count
Source
128
584k
            fn parse_be(i: I) -> IResult<I, Self, E> {
129
584k
                $be_fn(i)
130
584k
            }
131
0
            fn parse_le(i: I) -> IResult<I, Self, E> {
132
0
                $le_fn(i)
133
0
            }
Unexecuted instantiation: <u8 as nom_derive::traits::Parse<&[u8]>>::parse_le
Unexecuted instantiation: <u16 as nom_derive::traits::Parse<&[u8]>>::parse_le
Unexecuted instantiation: <u8 as nom_derive::traits::Parse<&[u8]>>::parse_le
Unexecuted instantiation: <u16 as nom_derive::traits::Parse<&[u8]>>::parse_le
134
        }
135
    };
136
}
137
138
impl_primitive_type!(i8, be_i8, le_i8);
139
impl_primitive_type!(i16, be_i16, le_i16);
140
impl_primitive_type!(i32, be_i32, le_i32);
141
impl_primitive_type!(i64, be_i64, le_i64);
142
impl_primitive_type!(i128, be_i128, le_i128);
143
144
impl_primitive_type!(u8, be_u8, le_u8);
145
impl_primitive_type!(u16, be_u16, le_u16);
146
impl_primitive_type!(u32, be_u32, le_u32);
147
impl_primitive_type!(u64, be_u64, le_u64);
148
impl_primitive_type!(u128, be_u128, le_u128);
149
150
impl_primitive_type!(f32, be_f32, le_f32);
151
impl_primitive_type!(f64, be_f64, le_f64);
152
153
impl<'a, E> Parse<&'a [u8], E> for String
154
where
155
    E: ParseError<&'a [u8]> + FromExternalError<&'a [u8], std::str::Utf8Error>,
156
{
157
    fn parse(i: &'a [u8]) -> IResult<&'a [u8], Self, E> {
158
        let (rem, sz) = <u32>::parse(i)?;
159
        let (rem, s) = map_res(take(sz as usize), std::str::from_utf8)(rem)?;
160
        Ok((rem, s.to_owned()))
161
    }
162
}
163
164
impl<T, I, E> Parse<I, E> for Option<T>
165
where
166
    I: Clone + InputSlice,
167
    E: ParseError<I>,
168
    T: Parse<I, E>,
169
{
170
    fn parse(i: I) -> IResult<I, Self, E> {
171
        opt(complete(<T>::parse))(i)
172
    }
173
    fn parse_be(i: I) -> IResult<I, Self, E> {
174
        opt(complete(<T>::parse_be))(i)
175
    }
176
    fn parse_le(i: I) -> IResult<I, Self, E> {
177
        opt(complete(<T>::parse_le))(i)
178
    }
179
}
180
181
impl<T, I, E> Parse<I, E> for Vec<T>
182
where
183
    I: Clone + PartialEq + InputSlice,
184
    E: ParseError<I>,
185
    T: Parse<I, E>,
186
{
187
    fn parse(i: I) -> IResult<I, Self, E> {
188
        many0(complete(<T>::parse))(i)
189
    }
190
    fn parse_be(i: I) -> IResult<I, Self, E> {
191
        many0(complete(<T>::parse_be))(i)
192
    }
193
    fn parse_le(i: I) -> IResult<I, Self, E> {
194
        many0(complete(<T>::parse_le))(i)
195
    }
196
}
197
198
impl<T1, T2, I, E> Parse<I, E> for (T1, T2)
199
where
200
    I: Clone + PartialEq + InputSlice,
201
    E: ParseError<I>,
202
    T1: Parse<I, E>,
203
    T2: Parse<I, E>,
204
{
205
    fn parse(i: I) -> IResult<I, Self, E> {
206
        pair(T1::parse, T2::parse)(i)
207
    }
208
    fn parse_be(i: I) -> IResult<I, Self, E> {
209
        pair(T1::parse_be, T2::parse_be)(i)
210
    }
211
    fn parse_le(i: I) -> IResult<I, Self, E> {
212
        pair(T1::parse_le, T2::parse_le)(i)
213
    }
214
}
215
216
/// *Note: this implementation uses const generics and requires rust >= 1.51*
217
#[rustversion::since(1.51)]
218
impl<T, I, E, const N: usize> Parse<I, E> for [T; N]
219
where
220
    I: Clone + PartialEq + InputSlice,
221
    E: ParseError<I> + FromExternalError<I, Vec<T>>,
222
    T: Parse<I, E>,
223
{
224
    fn parse(i: I) -> IResult<I, Self, E> {
225
        map_res(many_m_n(N, N, complete(<T>::parse)), Self::try_from)(i)
226
    }
227
    fn parse_be(i: I) -> IResult<I, Self, E> {
228
        map_res(many_m_n(N, N, complete(<T>::parse_be)), |v| {
229
            Self::try_from(v)
230
        })(i)
231
    }
232
    fn parse_le(i: I) -> IResult<I, Self, E> {
233
        map_res(many_m_n(N, N, complete(<T>::parse_le)), |v| {
234
            Self::try_from(v)
235
        })(i)
236
    }
237
}
238
239
#[cfg(test)]
240
mod tests {
241
    use super::*;
242
243
    #[test]
244
    fn test_parse_trait_vec() {
245
        let input: &[u8] = b"\x00\x01\x02\x03";
246
247
        type T = Vec<u8>;
248
        let res: IResult<_, _, Error<&[u8]>> = <T>::parse(input);
249
        assert_eq!(res.unwrap(), (b"" as &[u8], vec![0, 1, 2, 3]));
250
    }
251
252
    #[test]
253
    fn test_parse_trait_array() {
254
        let input: &[u8] = b"\x00\x01\x02\x03";
255
256
        type T = [u8; 4];
257
        let res: IResult<_, _, Error<&[u8]>> = <T>::parse(input);
258
        assert_eq!(res.unwrap(), (b"" as &[u8], [0, 1, 2, 3]));
259
    }
260
261
    #[test]
262
    fn test_parse_trait_string() {
263
        let input: &[u8] = b"\x00\x00\x00\x04abcd";
264
265
        type T = String;
266
        let res: IResult<_, _, Error<&[u8]>> = <T>::parse_le(input);
267
        assert_eq!(res.unwrap(), (b"" as &[u8], String::from("abcd")));
268
    }
269
}