1use nom::bytes::streaming::take;
2use nom::combinator::{complete, map_res, opt};
3use nom::error::{Error, FromExternalError, ParseError};
4use nom::multi::{many0, many_m_n};
5use nom::number::streaming::*;
6use nom::sequence::pair;
7use nom::*;
8use std::convert::TryFrom;
9use std::ops::RangeFrom;
10
11pub use nom::{InputLength, Slice};
12
13pub trait InputSlice:
14 Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength + InputTake
15{
16}
17impl<'a> InputSlice for &'a [u8] {}
18
19pub trait Parse<I, E = Error<I>>
96where
97 I: InputSlice,
98 E: ParseError<I>,
99 Self: Sized,
100{
101 fn parse(i: I) -> IResult<I, Self, E>;
106
107 fn parse_be(i: I) -> IResult<I, Self, E> {
109 Self::parse(i)
110 }
111
112 fn parse_le(i: I) -> IResult<I, Self, E> {
114 Self::parse(i)
115 }
116}
117
118macro_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 fn parse_be(i: I) -> IResult<I, Self, E> {
129 $be_fn(i)
130 }
131 fn parse_le(i: I) -> IResult<I, Self, E> {
132 $le_fn(i)
133 }
134 }
135 };
136}
137
138impl_primitive_type!(i8, be_i8, le_i8);
139impl_primitive_type!(i16, be_i16, le_i16);
140impl_primitive_type!(i32, be_i32, le_i32);
141impl_primitive_type!(i64, be_i64, le_i64);
142impl_primitive_type!(i128, be_i128, le_i128);
143
144impl_primitive_type!(u8, be_u8, le_u8);
145impl_primitive_type!(u16, be_u16, le_u16);
146impl_primitive_type!(u32, be_u32, le_u32);
147impl_primitive_type!(u64, be_u64, le_u64);
148impl_primitive_type!(u128, be_u128, le_u128);
149
150impl_primitive_type!(f32, be_f32, le_f32);
151impl_primitive_type!(f64, be_f64, le_f64);
152
153impl<'a, E> Parse<&'a [u8], E> for String
154where
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
164impl<T, I, E> Parse<I, E> for Option<T>
165where
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
181impl<T, I, E> Parse<I, E> for Vec<T>
182where
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
198impl<T1, T2, I, E> Parse<I, E> for (T1, T2)
199where
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#[rustversion::since(1.51)]
218impl<T, I, E, const N: usize> Parse<I, E> for [T; N]
219where
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)]
240mod 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}