1 //! Parsers recognizing numbers
2
3 #![allow(clippy::match_same_arms)]
4
5 pub mod bits;
6
7 #[cfg(test)]
8 mod tests;
9
10 use crate::combinator::repeat;
11 use crate::combinator::trace;
12 use crate::error::ErrMode;
13 use crate::error::ErrorKind;
14 use crate::error::Needed;
15 use crate::error::ParserError;
16 use crate::lib::std::ops::{Add, Shl};
17 use crate::stream::Accumulate;
18 use crate::stream::{AsBytes, Stream, StreamIsPartial};
19 use crate::stream::{ToUsize, UpdateSlice};
20 use crate::token::take;
21 use crate::PResult;
22 use crate::Parser;
23
24 /// Configurable endianness
25 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
26 pub enum Endianness {
27 /// Big endian
28 Big,
29 /// Little endian
30 Little,
31 /// Will match the host's endianness
32 Native,
33 }
34
35 /// Recognizes an unsigned 1 byte integer.
36 ///
37 /// *Complete version*: Returns an error if there is not enough input data.
38 ///
39 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
40 ///
41 /// # Example
42 ///
43 /// ```rust
44 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
45 /// # use winnow::prelude::*;
46 /// # use winnow::error::Needed::Size;
47 /// use winnow::binary::be_u8;
48 ///
49 /// fn parser(s: &[u8]) -> IResult<&[u8], u8> {
50 /// be_u8.parse_peek(s)
51 /// }
52 ///
53 /// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"\x03abcefg"[..], 0x00)));
54 /// assert_eq!(parser(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&[][..], ErrorKind::Token))));
55 /// ```
56 ///
57 /// ```rust
58 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
59 /// # use winnow::prelude::*;
60 /// # use winnow::Partial;
61 /// use winnow::binary::be_u8;
62 ///
63 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u8> {
64 /// be_u8.parse_peek(s)
65 /// }
66 ///
67 /// assert_eq!(parser(Partial::new(&b"\x00\x01abcd"[..])), Ok((Partial::new(&b"\x01abcd"[..]), 0x00)));
68 /// assert_eq!(parser(Partial::new(&b""[..])), Err(ErrMode::Incomplete(Needed::new(1))));
69 /// ```
70 #[inline(always)]
be_u8<I, E: ParserError<I>>(input: &mut I) -> PResult<u8, E> where I: StreamIsPartial, I: Stream<Token = u8>,71 pub fn be_u8<I, E: ParserError<I>>(input: &mut I) -> PResult<u8, E>
72 where
73 I: StreamIsPartial,
74 I: Stream<Token = u8>,
75 {
76 u8(input)
77 }
78
79 /// Recognizes a big endian unsigned 2 bytes integer.
80 ///
81 /// *Complete version*: Returns an error if there is not enough input data.
82 ///
83 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
84 ///
85 /// # Example
86 ///
87 /// ```rust
88 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
89 /// # use winnow::prelude::*;
90 /// # use winnow::error::Needed::Size;
91 /// use winnow::binary::be_u16;
92 ///
93 /// fn parser(s: &[u8]) -> IResult<&[u8], u16> {
94 /// be_u16.parse_peek(s)
95 /// }
96 ///
97 /// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0003)));
98 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
99 /// ```
100 ///
101 /// ```rust
102 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
103 /// # use winnow::prelude::*;
104 /// # use winnow::Partial;
105 /// use winnow::binary::be_u16;
106 ///
107 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u16> {
108 /// be_u16.parse_peek(s)
109 /// }
110 ///
111 /// assert_eq!(parser(Partial::new(&b"\x00\x01abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x0001)));
112 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
113 /// ```
114 #[inline(always)]
be_u16<I, E: ParserError<I>>(input: &mut I) -> PResult<u16, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,115 pub fn be_u16<I, E: ParserError<I>>(input: &mut I) -> PResult<u16, E>
116 where
117 I: StreamIsPartial,
118 I: Stream<Token = u8>,
119 <I as Stream>::Slice: AsBytes,
120 {
121 trace("be_u16", move |input: &mut I| be_uint(input, 2)).parse_next(input)
122 }
123
124 /// Recognizes a big endian unsigned 3 byte integer.
125 ///
126 /// *Complete version*: Returns an error if there is not enough input data.
127 ///
128 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
129 ///
130 /// # Example
131 ///
132 /// ```rust
133 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
134 /// # use winnow::prelude::*;
135 /// # use winnow::error::Needed::Size;
136 /// use winnow::binary::be_u24;
137 ///
138 /// fn parser(s: &[u8]) -> IResult<&[u8], u32> {
139 /// be_u24.parse_peek(s)
140 /// }
141 ///
142 /// assert_eq!(parser(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x000305)));
143 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
144 /// ```
145 ///
146 /// ```rust
147 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
148 /// # use winnow::prelude::*;
149 /// # use winnow::Partial;
150 /// use winnow::binary::be_u24;
151 ///
152 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> {
153 /// be_u24.parse_peek(s)
154 /// }
155 ///
156 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x000102)));
157 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2))));
158 /// ```
159 #[inline(always)]
be_u24<I, E: ParserError<I>>(input: &mut I) -> PResult<u32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,160 pub fn be_u24<I, E: ParserError<I>>(input: &mut I) -> PResult<u32, E>
161 where
162 I: StreamIsPartial,
163 I: Stream<Token = u8>,
164 <I as Stream>::Slice: AsBytes,
165 {
166 trace("be_u23", move |input: &mut I| be_uint(input, 3)).parse_next(input)
167 }
168
169 /// Recognizes a big endian unsigned 4 bytes integer.
170 ///
171 /// *Complete version*: Returns an error if there is not enough input data.
172 ///
173 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
174 ///
175 /// # Example
176 ///
177 /// ```rust
178 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
179 /// # use winnow::prelude::*;
180 /// # use winnow::error::Needed::Size;
181 /// use winnow::binary::be_u32;
182 ///
183 /// fn parser(s: &[u8]) -> IResult<&[u8], u32> {
184 /// be_u32.parse_peek(s)
185 /// }
186 ///
187 /// assert_eq!(parser(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00030507)));
188 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
189 /// ```
190 ///
191 /// ```rust
192 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
193 /// # use winnow::prelude::*;
194 /// # use winnow::Partial;
195 /// use winnow::binary::be_u32;
196 ///
197 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> {
198 /// be_u32.parse_peek(s)
199 /// }
200 ///
201 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02\x03abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x00010203)));
202 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3))));
203 /// ```
204 #[inline(always)]
be_u32<I, E: ParserError<I>>(input: &mut I) -> PResult<u32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,205 pub fn be_u32<I, E: ParserError<I>>(input: &mut I) -> PResult<u32, E>
206 where
207 I: StreamIsPartial,
208 I: Stream<Token = u8>,
209 <I as Stream>::Slice: AsBytes,
210 {
211 trace("be_u32", move |input: &mut I| be_uint(input, 4)).parse_next(input)
212 }
213
214 /// Recognizes a big endian unsigned 8 bytes integer.
215 ///
216 /// *Complete version*: Returns an error if there is not enough input data.
217 ///
218 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
219 ///
220 /// # Example
221 ///
222 /// ```rust
223 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
224 /// # use winnow::prelude::*;
225 /// # use winnow::error::Needed::Size;
226 /// use winnow::binary::be_u64;
227 ///
228 /// fn parser(s: &[u8]) -> IResult<&[u8], u64> {
229 /// be_u64.parse_peek(s)
230 /// }
231 ///
232 /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0001020304050607)));
233 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
234 /// ```
235 ///
236 /// ```rust
237 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
238 /// # use winnow::prelude::*;
239 /// # use winnow::Partial;
240 /// use winnow::binary::be_u64;
241 ///
242 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u64> {
243 /// be_u64.parse_peek(s)
244 /// }
245 ///
246 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x0001020304050607)));
247 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7))));
248 /// ```
249 #[inline(always)]
be_u64<I, E: ParserError<I>>(input: &mut I) -> PResult<u64, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,250 pub fn be_u64<I, E: ParserError<I>>(input: &mut I) -> PResult<u64, E>
251 where
252 I: StreamIsPartial,
253 I: Stream<Token = u8>,
254 <I as Stream>::Slice: AsBytes,
255 {
256 trace("be_u64", move |input: &mut I| be_uint(input, 8)).parse_next(input)
257 }
258
259 /// Recognizes a big endian unsigned 16 bytes integer.
260 ///
261 /// *Complete version*: Returns an error if there is not enough input data.
262 ///
263 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
264 ///
265 /// # Example
266 ///
267 /// ```rust
268 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
269 /// # use winnow::prelude::*;
270 /// # use winnow::error::Needed::Size;
271 /// use winnow::binary::be_u128;
272 ///
273 /// fn parser(s: &[u8]) -> IResult<&[u8], u128> {
274 /// be_u128.parse_peek(s)
275 /// }
276 ///
277 /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00010203040506070001020304050607)));
278 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
279 /// ```
280 ///
281 /// ```rust
282 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
283 /// # use winnow::prelude::*;
284 /// # use winnow::Partial;
285 /// use winnow::binary::be_u128;
286 ///
287 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u128> {
288 /// be_u128.parse_peek(s)
289 /// }
290 ///
291 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x00010203040506070809101112131415)));
292 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15))));
293 /// ```
294 #[inline(always)]
be_u128<I, E: ParserError<I>>(input: &mut I) -> PResult<u128, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,295 pub fn be_u128<I, E: ParserError<I>>(input: &mut I) -> PResult<u128, E>
296 where
297 I: StreamIsPartial,
298 I: Stream<Token = u8>,
299 <I as Stream>::Slice: AsBytes,
300 {
301 trace("be_u128", move |input: &mut I| be_uint(input, 16)).parse_next(input)
302 }
303
304 #[inline]
be_uint<I, Uint, E: ParserError<I>>(input: &mut I, bound: usize) -> PResult<Uint, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes, Uint: Default + Shl<u8, Output = Uint> + Add<Uint, Output = Uint> + From<u8>,305 fn be_uint<I, Uint, E: ParserError<I>>(input: &mut I, bound: usize) -> PResult<Uint, E>
306 where
307 I: StreamIsPartial,
308 I: Stream<Token = u8>,
309 <I as Stream>::Slice: AsBytes,
310 Uint: Default + Shl<u8, Output = Uint> + Add<Uint, Output = Uint> + From<u8>,
311 {
312 debug_assert_ne!(bound, 1, "to_be_uint needs extra work to avoid overflow");
313 take(bound)
314 .map(|n: <I as Stream>::Slice| to_be_uint(n.as_bytes()))
315 .parse_next(input)
316 }
317
318 #[inline]
to_be_uint<Uint>(number: &[u8]) -> Uint where Uint: Default + Shl<u8, Output = Uint> + Add<Uint, Output = Uint> + From<u8>,319 fn to_be_uint<Uint>(number: &[u8]) -> Uint
320 where
321 Uint: Default + Shl<u8, Output = Uint> + Add<Uint, Output = Uint> + From<u8>,
322 {
323 let mut res = Uint::default();
324 for byte in number.iter().copied() {
325 res = (res << 8) + byte.into();
326 }
327
328 res
329 }
330
331 /// Recognizes a signed 1 byte integer.
332 ///
333 /// *Complete version*: Returns an error if there is not enough input data.
334 ///
335 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
336 ///
337 /// # Example
338 ///
339 /// ```rust
340 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
341 /// # use winnow::prelude::*;
342 /// # use winnow::error::Needed::Size;
343 /// use winnow::binary::be_i8;
344 ///
345 /// fn parser(s: &[u8]) -> IResult<&[u8], i8> {
346 /// be_i8.parse_peek(s)
347 /// }
348 ///
349 /// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"\x03abcefg"[..], 0x00)));
350 /// assert_eq!(parser(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&[][..], ErrorKind::Token))));
351 /// ```
352 ///
353 /// ```rust
354 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
355 /// # use winnow::prelude::*;
356 /// # use winnow::Partial;
357 /// use winnow::binary::be_i8;
358 ///
359 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i8> {
360 /// be_i8.parse_peek(s)
361 /// }
362 ///
363 /// assert_eq!(parser(Partial::new(&b"\x00\x01abcd"[..])), Ok((Partial::new(&b"\x01abcd"[..]), 0x00)));
364 /// assert_eq!(parser(Partial::new(&b""[..])), Err(ErrMode::Incomplete(Needed::new(1))));
365 /// ```
366 #[inline(always)]
be_i8<I, E: ParserError<I>>(input: &mut I) -> PResult<i8, E> where I: StreamIsPartial, I: Stream<Token = u8>,367 pub fn be_i8<I, E: ParserError<I>>(input: &mut I) -> PResult<i8, E>
368 where
369 I: StreamIsPartial,
370 I: Stream<Token = u8>,
371 {
372 i8(input)
373 }
374
375 /// Recognizes a big endian signed 2 bytes integer.
376 ///
377 /// *Complete version*: Returns an error if there is not enough input data.
378 ///
379 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
380 ///
381 /// # Example
382 ///
383 /// ```rust
384 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
385 /// # use winnow::prelude::*;
386 /// # use winnow::error::Needed::Size;
387 /// use winnow::binary::be_i16;
388 ///
389 /// fn parser(s: &[u8]) -> IResult<&[u8], i16> {
390 /// be_i16.parse_peek(s)
391 /// }
392 ///
393 /// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0003)));
394 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
395 /// ```
396 ///
397 /// ```rust
398 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
399 /// # use winnow::prelude::*;
400 /// # use winnow::Partial;
401 /// use winnow::binary::be_i16;
402 ///
403 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i16> {
404 /// be_i16.parse_peek(s)
405 /// }
406 ///
407 /// assert_eq!(parser(Partial::new(&b"\x00\x01abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x0001)));
408 /// assert_eq!(parser(Partial::new(&b""[..])), Err(ErrMode::Incomplete(Needed::new(2))));
409 /// ```
410 #[inline(always)]
be_i16<I, E: ParserError<I>>(input: &mut I) -> PResult<i16, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,411 pub fn be_i16<I, E: ParserError<I>>(input: &mut I) -> PResult<i16, E>
412 where
413 I: StreamIsPartial,
414 I: Stream<Token = u8>,
415 <I as Stream>::Slice: AsBytes,
416 {
417 trace("be_i16", move |input: &mut I| {
418 be_uint::<_, u16, _>(input, 2).map(|n| n as i16)
419 })
420 .parse_next(input)
421 }
422
423 /// Recognizes a big endian signed 3 bytes integer.
424 ///
425 /// *Complete version*: Returns an error if there is not enough input data.
426 ///
427 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
428 ///
429 /// # Example
430 ///
431 /// ```rust
432 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
433 /// # use winnow::prelude::*;
434 /// # use winnow::error::Needed::Size;
435 /// use winnow::binary::be_i24;
436 ///
437 /// fn parser(s: &[u8]) -> IResult<&[u8], i32> {
438 /// be_i24.parse_peek(s)
439 /// }
440 ///
441 /// assert_eq!(parser(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x000305)));
442 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
443 /// ```
444 ///
445 /// ```rust
446 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
447 /// # use winnow::prelude::*;
448 /// # use winnow::Partial;
449 /// use winnow::binary::be_i24;
450 ///
451 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i32> {
452 /// be_i24.parse_peek(s)
453 /// }
454 ///
455 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x000102)));
456 /// assert_eq!(parser(Partial::new(&b""[..])), Err(ErrMode::Incomplete(Needed::new(3))));
457 /// ```
458 #[inline(always)]
be_i24<I, E: ParserError<I>>(input: &mut I) -> PResult<i32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,459 pub fn be_i24<I, E: ParserError<I>>(input: &mut I) -> PResult<i32, E>
460 where
461 I: StreamIsPartial,
462 I: Stream<Token = u8>,
463 <I as Stream>::Slice: AsBytes,
464 {
465 trace("be_i24", move |input: &mut I| {
466 be_uint::<_, u32, _>(input, 3).map(|n| {
467 // Same as the unsigned version but we need to sign-extend manually here
468 let n = if n & 0x80_00_00 != 0 {
469 (n | 0xff_00_00_00) as i32
470 } else {
471 n as i32
472 };
473 n
474 })
475 })
476 .parse_next(input)
477 }
478
479 /// Recognizes a big endian signed 4 bytes integer.
480 ///
481 /// *Complete version*: Returns an error if there is not enough input data.
482 ///
483 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
484 ///
485 /// # Example
486 ///
487 /// ```rust
488 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
489 /// # use winnow::prelude::*;
490 /// # use winnow::error::Needed::Size;
491 /// use winnow::binary::be_i32;
492 ///
493 /// fn parser(s: &[u8]) -> IResult<&[u8], i32> {
494 /// be_i32.parse_peek(s)
495 /// }
496 ///
497 /// assert_eq!(parser(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00030507)));
498 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
499 /// ```
500 ///
501 /// ```rust
502 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
503 /// # use winnow::prelude::*;
504 /// # use winnow::Partial;
505 /// use winnow::binary::be_i32;
506 ///
507 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i32> {
508 /// be_i32.parse_peek(s)
509 /// }
510 ///
511 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02\x03abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x00010203)));
512 /// assert_eq!(parser(Partial::new(&b""[..])), Err(ErrMode::Incomplete(Needed::new(4))));
513 /// ```
514 #[inline(always)]
be_i32<I, E: ParserError<I>>(input: &mut I) -> PResult<i32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,515 pub fn be_i32<I, E: ParserError<I>>(input: &mut I) -> PResult<i32, E>
516 where
517 I: StreamIsPartial,
518 I: Stream<Token = u8>,
519 <I as Stream>::Slice: AsBytes,
520 {
521 trace("be_i32", move |input: &mut I| {
522 be_uint::<_, u32, _>(input, 4).map(|n| n as i32)
523 })
524 .parse_next(input)
525 }
526
527 /// Recognizes a big endian signed 8 bytes integer.
528 ///
529 /// *Complete version*: Returns an error if there is not enough input data.
530 ///
531 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
532 ///
533 /// # Example
534 ///
535 /// ```rust
536 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
537 /// # use winnow::prelude::*;
538 /// # use winnow::error::Needed::Size;
539 /// use winnow::binary::be_i64;
540 ///
541 /// fn parser(s: &[u8]) -> IResult<&[u8], i64> {
542 /// be_i64.parse_peek(s)
543 /// }
544 ///
545 /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0001020304050607)));
546 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
547 /// ```
548 ///
549 /// ```rust
550 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
551 /// # use winnow::prelude::*;
552 /// # use winnow::Partial;
553 /// use winnow::binary::be_i64;
554 ///
555 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i64> {
556 /// be_i64.parse_peek(s)
557 /// }
558 ///
559 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x0001020304050607)));
560 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7))));
561 /// ```
562 #[inline(always)]
be_i64<I, E: ParserError<I>>(input: &mut I) -> PResult<i64, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,563 pub fn be_i64<I, E: ParserError<I>>(input: &mut I) -> PResult<i64, E>
564 where
565 I: StreamIsPartial,
566 I: Stream<Token = u8>,
567 <I as Stream>::Slice: AsBytes,
568 {
569 trace("be_i64", move |input: &mut I| {
570 be_uint::<_, u64, _>(input, 8).map(|n| n as i64)
571 })
572 .parse_next(input)
573 }
574
575 /// Recognizes a big endian signed 16 bytes integer.
576 ///
577 /// *Complete version*: Returns an error if there is not enough input data.
578 ///
579 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
580 ///
581 /// # Example
582 ///
583 /// ```rust
584 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
585 /// # use winnow::prelude::*;
586 /// # use winnow::error::Needed::Size;
587 /// use winnow::binary::be_i128;
588 ///
589 /// fn parser(s: &[u8]) -> IResult<&[u8], i128> {
590 /// be_i128.parse_peek(s)
591 /// }
592 ///
593 /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00010203040506070001020304050607)));
594 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
595 /// ```
596 ///
597 /// ```rust
598 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
599 /// # use winnow::prelude::*;
600 /// # use winnow::Partial;
601 /// use winnow::binary::be_i128;
602 ///
603 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i128> {
604 /// be_i128.parse_peek(s)
605 /// }
606 ///
607 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x00010203040506070809101112131415)));
608 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15))));
609 /// ```
610 #[inline(always)]
be_i128<I, E: ParserError<I>>(input: &mut I) -> PResult<i128, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,611 pub fn be_i128<I, E: ParserError<I>>(input: &mut I) -> PResult<i128, E>
612 where
613 I: StreamIsPartial,
614 I: Stream<Token = u8>,
615 <I as Stream>::Slice: AsBytes,
616 {
617 trace("be_i128", move |input: &mut I| {
618 be_uint::<_, u128, _>(input, 16).map(|n| n as i128)
619 })
620 .parse_next(input)
621 }
622
623 /// Recognizes an unsigned 1 byte integer.
624 ///
625 /// *Complete version*: Returns an error if there is not enough input data.
626 ///
627 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
628 ///
629 /// # Example
630 ///
631 /// ```rust
632 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
633 /// # use winnow::prelude::*;
634 /// # use winnow::error::Needed::Size;
635 /// use winnow::binary::le_u8;
636 ///
637 /// fn parser(s: &[u8]) -> IResult<&[u8], u8> {
638 /// le_u8.parse_peek(s)
639 /// }
640 ///
641 /// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"\x03abcefg"[..], 0x00)));
642 /// assert_eq!(parser(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&[][..], ErrorKind::Token))));
643 /// ```
644 ///
645 /// ```rust
646 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
647 /// # use winnow::prelude::*;
648 /// # use winnow::Partial;
649 /// use winnow::binary::le_u8;
650 ///
651 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u8> {
652 /// le_u8.parse_peek(s)
653 /// }
654 ///
655 /// assert_eq!(parser(Partial::new(&b"\x00\x01abcd"[..])), Ok((Partial::new(&b"\x01abcd"[..]), 0x00)));
656 /// assert_eq!(parser(Partial::new(&b""[..])), Err(ErrMode::Incomplete(Needed::new(1))));
657 /// ```
658 #[inline(always)]
le_u8<I, E: ParserError<I>>(input: &mut I) -> PResult<u8, E> where I: StreamIsPartial, I: Stream<Token = u8>,659 pub fn le_u8<I, E: ParserError<I>>(input: &mut I) -> PResult<u8, E>
660 where
661 I: StreamIsPartial,
662 I: Stream<Token = u8>,
663 {
664 u8(input)
665 }
666
667 /// Recognizes a little endian unsigned 2 bytes integer.
668 ///
669 /// *Complete version*: Returns an error if there is not enough input data.
670 ///
671 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
672 ///
673 /// # Example
674 ///
675 /// ```rust
676 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
677 /// # use winnow::prelude::*;
678 /// # use winnow::error::Needed::Size;
679 /// use winnow::binary::le_u16;
680 ///
681 /// fn parser(s: &[u8]) -> IResult<&[u8], u16> {
682 /// le_u16.parse_peek(s)
683 /// }
684 ///
685 /// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0300)));
686 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
687 /// ```
688 ///
689 /// ```rust
690 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
691 /// # use winnow::prelude::*;
692 /// # use winnow::Partial;
693 /// use winnow::binary::le_u16;
694 ///
695 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u16> {
696 /// le_u16::<_, InputError<_>>.parse_peek(s)
697 /// }
698 ///
699 /// assert_eq!(parser(Partial::new(&b"\x00\x01abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x0100)));
700 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
701 /// ```
702 #[inline(always)]
le_u16<I, E: ParserError<I>>(input: &mut I) -> PResult<u16, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,703 pub fn le_u16<I, E: ParserError<I>>(input: &mut I) -> PResult<u16, E>
704 where
705 I: StreamIsPartial,
706 I: Stream<Token = u8>,
707 <I as Stream>::Slice: AsBytes,
708 {
709 trace("le_u16", move |input: &mut I| le_uint(input, 2)).parse_next(input)
710 }
711
712 /// Recognizes a little endian unsigned 3 byte integer.
713 ///
714 /// *Complete version*: Returns an error if there is not enough input data.
715 ///
716 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
717 ///
718 /// # Example
719 ///
720 /// ```rust
721 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
722 /// # use winnow::prelude::*;
723 /// # use winnow::error::Needed::Size;
724 /// use winnow::binary::le_u24;
725 ///
726 /// fn parser(s: &[u8]) -> IResult<&[u8], u32> {
727 /// le_u24.parse_peek(s)
728 /// }
729 ///
730 /// assert_eq!(parser(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x050300)));
731 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
732 /// ```
733 ///
734 /// ```rust
735 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
736 /// # use winnow::prelude::*;
737 /// # use winnow::Partial;
738 /// use winnow::binary::le_u24;
739 ///
740 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> {
741 /// le_u24::<_, InputError<_>>.parse_peek(s)
742 /// }
743 ///
744 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x020100)));
745 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2))));
746 /// ```
747 #[inline(always)]
le_u24<I, E: ParserError<I>>(input: &mut I) -> PResult<u32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,748 pub fn le_u24<I, E: ParserError<I>>(input: &mut I) -> PResult<u32, E>
749 where
750 I: StreamIsPartial,
751 I: Stream<Token = u8>,
752 <I as Stream>::Slice: AsBytes,
753 {
754 trace("le_u24", move |input: &mut I| le_uint(input, 3)).parse_next(input)
755 }
756
757 /// Recognizes a little endian unsigned 4 bytes integer.
758 ///
759 /// *Complete version*: Returns an error if there is not enough input data.
760 ///
761 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
762 ///
763 /// # Example
764 ///
765 /// ```rust
766 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
767 /// # use winnow::prelude::*;
768 /// # use winnow::error::Needed::Size;
769 /// use winnow::binary::le_u32;
770 ///
771 /// fn parser(s: &[u8]) -> IResult<&[u8], u32> {
772 /// le_u32.parse_peek(s)
773 /// }
774 ///
775 /// assert_eq!(parser(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07050300)));
776 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
777 /// ```
778 ///
779 /// ```rust
780 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
781 /// # use winnow::prelude::*;
782 /// # use winnow::Partial;
783 /// use winnow::binary::le_u32;
784 ///
785 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u32> {
786 /// le_u32::<_, InputError<_>>.parse_peek(s)
787 /// }
788 ///
789 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02\x03abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x03020100)));
790 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3))));
791 /// ```
792 #[inline(always)]
le_u32<I, E: ParserError<I>>(input: &mut I) -> PResult<u32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,793 pub fn le_u32<I, E: ParserError<I>>(input: &mut I) -> PResult<u32, E>
794 where
795 I: StreamIsPartial,
796 I: Stream<Token = u8>,
797 <I as Stream>::Slice: AsBytes,
798 {
799 trace("le_u32", move |input: &mut I| le_uint(input, 4)).parse_next(input)
800 }
801
802 /// Recognizes a little endian unsigned 8 bytes integer.
803 ///
804 /// *Complete version*: Returns an error if there is not enough input data.
805 ///
806 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
807 ///
808 /// # Example
809 ///
810 /// ```rust
811 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
812 /// # use winnow::prelude::*;
813 /// # use winnow::error::Needed::Size;
814 /// use winnow::binary::le_u64;
815 ///
816 /// fn parser(s: &[u8]) -> IResult<&[u8], u64> {
817 /// le_u64.parse_peek(s)
818 /// }
819 ///
820 /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0706050403020100)));
821 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
822 /// ```
823 ///
824 /// ```rust
825 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
826 /// # use winnow::prelude::*;
827 /// # use winnow::Partial;
828 /// use winnow::binary::le_u64;
829 ///
830 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u64> {
831 /// le_u64::<_, InputError<_>>.parse_peek(s)
832 /// }
833 ///
834 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x0706050403020100)));
835 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7))));
836 /// ```
837 #[inline(always)]
le_u64<I, E: ParserError<I>>(input: &mut I) -> PResult<u64, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,838 pub fn le_u64<I, E: ParserError<I>>(input: &mut I) -> PResult<u64, E>
839 where
840 I: StreamIsPartial,
841 I: Stream<Token = u8>,
842 <I as Stream>::Slice: AsBytes,
843 {
844 trace("le_u64", move |input: &mut I| le_uint(input, 8)).parse_next(input)
845 }
846
847 /// Recognizes a little endian unsigned 16 bytes integer.
848 ///
849 /// *Complete version*: Returns an error if there is not enough input data.
850 ///
851 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
852 ///
853 /// # Example
854 ///
855 /// ```rust
856 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
857 /// # use winnow::prelude::*;
858 /// # use winnow::error::Needed::Size;
859 /// use winnow::binary::le_u128;
860 ///
861 /// fn parser(s: &[u8]) -> IResult<&[u8], u128> {
862 /// le_u128.parse_peek(s)
863 /// }
864 ///
865 /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07060504030201000706050403020100)));
866 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
867 /// ```
868 ///
869 /// ```rust
870 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
871 /// # use winnow::prelude::*;
872 /// # use winnow::Partial;
873 /// use winnow::binary::le_u128;
874 ///
875 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u128> {
876 /// le_u128::<_, InputError<_>>.parse_peek(s)
877 /// }
878 ///
879 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x15141312111009080706050403020100)));
880 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15))));
881 /// ```
882 #[inline(always)]
le_u128<I, E: ParserError<I>>(input: &mut I) -> PResult<u128, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,883 pub fn le_u128<I, E: ParserError<I>>(input: &mut I) -> PResult<u128, E>
884 where
885 I: StreamIsPartial,
886 I: Stream<Token = u8>,
887 <I as Stream>::Slice: AsBytes,
888 {
889 trace("le_u128", move |input: &mut I| le_uint(input, 16)).parse_next(input)
890 }
891
892 #[inline]
le_uint<I, Uint, E: ParserError<I>>(input: &mut I, bound: usize) -> PResult<Uint, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes, Uint: Default + Shl<u8, Output = Uint> + Add<Uint, Output = Uint> + From<u8>,893 fn le_uint<I, Uint, E: ParserError<I>>(input: &mut I, bound: usize) -> PResult<Uint, E>
894 where
895 I: StreamIsPartial,
896 I: Stream<Token = u8>,
897 <I as Stream>::Slice: AsBytes,
898 Uint: Default + Shl<u8, Output = Uint> + Add<Uint, Output = Uint> + From<u8>,
899 {
900 take(bound)
901 .map(|n: <I as Stream>::Slice| to_le_uint(n.as_bytes()))
902 .parse_next(input)
903 }
904
905 #[inline]
to_le_uint<Uint>(number: &[u8]) -> Uint where Uint: Default + Shl<u8, Output = Uint> + Add<Uint, Output = Uint> + From<u8>,906 fn to_le_uint<Uint>(number: &[u8]) -> Uint
907 where
908 Uint: Default + Shl<u8, Output = Uint> + Add<Uint, Output = Uint> + From<u8>,
909 {
910 let mut res = Uint::default();
911 for (index, byte) in number.iter_offsets() {
912 res = res + (Uint::from(byte) << (8 * index as u8));
913 }
914
915 res
916 }
917
918 /// Recognizes a signed 1 byte integer.
919 ///
920 /// *Complete version*: Returns an error if there is not enough input data.
921 ///
922 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
923 ///
924 /// # Example
925 ///
926 /// ```rust
927 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
928 /// # use winnow::prelude::*;
929 /// # use winnow::error::Needed::Size;
930 /// use winnow::binary::le_i8;
931 ///
932 /// fn parser(s: &[u8]) -> IResult<&[u8], i8> {
933 /// le_i8.parse_peek(s)
934 /// }
935 ///
936 /// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"\x03abcefg"[..], 0x00)));
937 /// assert_eq!(parser(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&[][..], ErrorKind::Token))));
938 /// ```
939 ///
940 /// ```rust
941 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
942 /// # use winnow::prelude::*;
943 /// # use winnow::Partial;
944 /// use winnow::binary::le_i8;
945 ///
946 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i8> {
947 /// le_i8.parse_peek(s)
948 /// }
949 ///
950 /// assert_eq!(parser(Partial::new(&b"\x00\x01abcd"[..])), Ok((Partial::new(&b"\x01abcd"[..]), 0x00)));
951 /// assert_eq!(parser(Partial::new(&b""[..])), Err(ErrMode::Incomplete(Needed::new(1))));
952 /// ```
953 #[inline(always)]
le_i8<I, E: ParserError<I>>(input: &mut I) -> PResult<i8, E> where I: StreamIsPartial, I: Stream<Token = u8>,954 pub fn le_i8<I, E: ParserError<I>>(input: &mut I) -> PResult<i8, E>
955 where
956 I: StreamIsPartial,
957 I: Stream<Token = u8>,
958 {
959 i8(input)
960 }
961
962 /// Recognizes a little endian signed 2 bytes integer.
963 ///
964 /// *Complete version*: Returns an error if there is not enough input data.
965 ///
966 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
967 ///
968 /// # Example
969 ///
970 /// ```rust
971 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
972 /// # use winnow::prelude::*;
973 /// # use winnow::error::Needed::Size;
974 /// use winnow::binary::le_i16;
975 ///
976 /// fn parser(s: &[u8]) -> IResult<&[u8], i16> {
977 /// le_i16.parse_peek(s)
978 /// }
979 ///
980 /// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0300)));
981 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
982 /// ```
983 ///
984 /// ```rust
985 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
986 /// # use winnow::prelude::*;
987 /// # use winnow::Partial;
988 /// use winnow::binary::le_i16;
989 ///
990 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i16> {
991 /// le_i16::<_, InputError<_>>.parse_peek(s)
992 /// }
993 ///
994 /// assert_eq!(parser(Partial::new(&b"\x00\x01abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x0100)));
995 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
996 /// ```
997 #[inline(always)]
le_i16<I, E: ParserError<I>>(input: &mut I) -> PResult<i16, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,998 pub fn le_i16<I, E: ParserError<I>>(input: &mut I) -> PResult<i16, E>
999 where
1000 I: StreamIsPartial,
1001 I: Stream<Token = u8>,
1002 <I as Stream>::Slice: AsBytes,
1003 {
1004 trace("le_i16", move |input: &mut I| {
1005 le_uint::<_, u16, _>(input, 2).map(|n| n as i16)
1006 })
1007 .parse_next(input)
1008 }
1009
1010 /// Recognizes a little endian signed 3 bytes integer.
1011 ///
1012 /// *Complete version*: Returns an error if there is not enough input data.
1013 ///
1014 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1015 ///
1016 /// # Example
1017 ///
1018 /// ```rust
1019 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1020 /// # use winnow::prelude::*;
1021 /// # use winnow::error::Needed::Size;
1022 /// use winnow::binary::le_i24;
1023 ///
1024 /// fn parser(s: &[u8]) -> IResult<&[u8], i32> {
1025 /// le_i24.parse_peek(s)
1026 /// }
1027 ///
1028 /// assert_eq!(parser(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x050300)));
1029 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1030 /// ```
1031 ///
1032 /// ```rust
1033 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1034 /// # use winnow::prelude::*;
1035 /// # use winnow::Partial;
1036 /// use winnow::binary::le_i24;
1037 ///
1038 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i32> {
1039 /// le_i24::<_, InputError<_>>.parse_peek(s)
1040 /// }
1041 ///
1042 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x020100)));
1043 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2))));
1044 /// ```
1045 #[inline(always)]
le_i24<I, E: ParserError<I>>(input: &mut I) -> PResult<i32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1046 pub fn le_i24<I, E: ParserError<I>>(input: &mut I) -> PResult<i32, E>
1047 where
1048 I: StreamIsPartial,
1049 I: Stream<Token = u8>,
1050 <I as Stream>::Slice: AsBytes,
1051 {
1052 trace("le_i24", move |input: &mut I| {
1053 le_uint::<_, u32, _>(input, 3).map(|n| {
1054 // Same as the unsigned version but we need to sign-extend manually here
1055 let n = if n & 0x80_00_00 != 0 {
1056 (n | 0xff_00_00_00) as i32
1057 } else {
1058 n as i32
1059 };
1060 n
1061 })
1062 })
1063 .parse_next(input)
1064 }
1065
1066 /// Recognizes a little endian signed 4 bytes integer.
1067 ///
1068 /// *Complete version*: Returns an error if there is not enough input data.
1069 ///
1070 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1071 ///
1072 /// # Example
1073 ///
1074 /// ```rust
1075 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1076 /// # use winnow::prelude::*;
1077 /// # use winnow::error::Needed::Size;
1078 /// use winnow::binary::le_i32;
1079 ///
1080 /// fn parser(s: &[u8]) -> IResult<&[u8], i32> {
1081 /// le_i32.parse_peek(s)
1082 /// }
1083 ///
1084 /// assert_eq!(parser(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07050300)));
1085 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1086 /// ```
1087 ///
1088 /// ```rust
1089 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1090 /// # use winnow::prelude::*;
1091 /// # use winnow::Partial;
1092 /// use winnow::binary::le_i32;
1093 ///
1094 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i32> {
1095 /// le_i32::<_, InputError<_>>.parse_peek(s)
1096 /// }
1097 ///
1098 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02\x03abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x03020100)));
1099 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3))));
1100 /// ```
1101 #[inline(always)]
le_i32<I, E: ParserError<I>>(input: &mut I) -> PResult<i32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1102 pub fn le_i32<I, E: ParserError<I>>(input: &mut I) -> PResult<i32, E>
1103 where
1104 I: StreamIsPartial,
1105 I: Stream<Token = u8>,
1106 <I as Stream>::Slice: AsBytes,
1107 {
1108 trace("le_i32", move |input: &mut I| {
1109 le_uint::<_, u32, _>(input, 4).map(|n| n as i32)
1110 })
1111 .parse_next(input)
1112 }
1113
1114 /// Recognizes a little endian signed 8 bytes integer.
1115 ///
1116 /// *Complete version*: Returns an error if there is not enough input data.
1117 ///
1118 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1119 ///
1120 /// # Example
1121 ///
1122 /// ```rust
1123 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1124 /// # use winnow::prelude::*;
1125 /// # use winnow::error::Needed::Size;
1126 /// use winnow::binary::le_i64;
1127 ///
1128 /// fn parser(s: &[u8]) -> IResult<&[u8], i64> {
1129 /// le_i64.parse_peek(s)
1130 /// }
1131 ///
1132 /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0706050403020100)));
1133 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1134 /// ```
1135 ///
1136 /// ```rust
1137 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1138 /// # use winnow::prelude::*;
1139 /// # use winnow::Partial;
1140 /// use winnow::binary::le_i64;
1141 ///
1142 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i64> {
1143 /// le_i64::<_, InputError<_>>.parse_peek(s)
1144 /// }
1145 ///
1146 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x0706050403020100)));
1147 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7))));
1148 /// ```
1149 #[inline(always)]
le_i64<I, E: ParserError<I>>(input: &mut I) -> PResult<i64, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1150 pub fn le_i64<I, E: ParserError<I>>(input: &mut I) -> PResult<i64, E>
1151 where
1152 I: StreamIsPartial,
1153 I: Stream<Token = u8>,
1154 <I as Stream>::Slice: AsBytes,
1155 {
1156 trace("le_i64", move |input: &mut I| {
1157 le_uint::<_, u64, _>(input, 8).map(|n| n as i64)
1158 })
1159 .parse_next(input)
1160 }
1161
1162 /// Recognizes a little endian signed 16 bytes integer.
1163 ///
1164 /// *Complete version*: Returns an error if there is not enough input data.
1165 ///
1166 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1167 ///
1168 /// # Example
1169 ///
1170 /// ```rust
1171 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1172 /// # use winnow::prelude::*;
1173 /// # use winnow::error::Needed::Size;
1174 /// use winnow::binary::le_i128;
1175 ///
1176 /// fn parser(s: &[u8]) -> IResult<&[u8], i128> {
1177 /// le_i128.parse_peek(s)
1178 /// }
1179 ///
1180 /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07060504030201000706050403020100)));
1181 /// assert_eq!(parser(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1182 /// ```
1183 ///
1184 /// ```rust
1185 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1186 /// # use winnow::prelude::*;
1187 /// # use winnow::Partial;
1188 /// use winnow::binary::le_i128;
1189 ///
1190 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i128> {
1191 /// le_i128::<_, InputError<_>>.parse_peek(s)
1192 /// }
1193 ///
1194 /// assert_eq!(parser(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15abcd"[..])), Ok((Partial::new(&b"abcd"[..]), 0x15141312111009080706050403020100)));
1195 /// assert_eq!(parser(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15))));
1196 /// ```
1197 #[inline(always)]
le_i128<I, E: ParserError<I>>(input: &mut I) -> PResult<i128, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1198 pub fn le_i128<I, E: ParserError<I>>(input: &mut I) -> PResult<i128, E>
1199 where
1200 I: StreamIsPartial,
1201 I: Stream<Token = u8>,
1202 <I as Stream>::Slice: AsBytes,
1203 {
1204 trace("le_i128", move |input: &mut I| {
1205 le_uint::<_, u128, _>(input, 16).map(|n| n as i128)
1206 })
1207 .parse_next(input)
1208 }
1209
1210 /// Recognizes an unsigned 1 byte integer
1211 ///
1212 /// **Note:** that endianness does not apply to 1 byte numbers.
1213 ///
1214 /// *Complete version*: returns an error if there is not enough input data
1215 ///
1216 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1217 ///
1218 /// # Example
1219 ///
1220 /// ```rust
1221 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1222 /// # use winnow::prelude::*;
1223 /// # use winnow::error::Needed::Size;
1224 /// use winnow::binary::u8;
1225 ///
1226 /// fn parser(s: &[u8]) -> IResult<&[u8], u8> {
1227 /// u8.parse_peek(s)
1228 /// }
1229 ///
1230 /// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"\x03abcefg"[..], 0x00)));
1231 /// assert_eq!(parser(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&[][..], ErrorKind::Token))));
1232 /// ```
1233 ///
1234 /// ```rust
1235 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1236 /// # use winnow::prelude::*;
1237 /// # use winnow::error::Needed::Size;
1238 /// # use winnow::Partial;
1239 /// use winnow::binary::u8;
1240 ///
1241 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u8> {
1242 /// u8::<_, InputError<_>>.parse_peek(s)
1243 /// }
1244 ///
1245 /// assert_eq!(parser(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"\x03abcefg"[..]), 0x00)));
1246 /// assert_eq!(parser(Partial::new(&b""[..])), Err(ErrMode::Incomplete(Needed::new(1))));
1247 /// ```
1248 #[inline(always)]
u8<I, E: ParserError<I>>(input: &mut I) -> PResult<u8, E> where I: StreamIsPartial, I: Stream<Token = u8>,1249 pub fn u8<I, E: ParserError<I>>(input: &mut I) -> PResult<u8, E>
1250 where
1251 I: StreamIsPartial,
1252 I: Stream<Token = u8>,
1253 {
1254 trace("u8", move |input: &mut I| {
1255 if <I as StreamIsPartial>::is_partial_supported() {
1256 u8_::<_, _, true>(input)
1257 } else {
1258 u8_::<_, _, false>(input)
1259 }
1260 })
1261 .parse_next(input)
1262 }
1263
u8_<I, E: ParserError<I>, const PARTIAL: bool>(input: &mut I) -> PResult<u8, E> where I: StreamIsPartial, I: Stream<Token = u8>,1264 fn u8_<I, E: ParserError<I>, const PARTIAL: bool>(input: &mut I) -> PResult<u8, E>
1265 where
1266 I: StreamIsPartial,
1267 I: Stream<Token = u8>,
1268 {
1269 input.next_token().ok_or_else(|| {
1270 if PARTIAL && input.is_partial() {
1271 ErrMode::Incomplete(Needed::new(1))
1272 } else {
1273 ErrMode::Backtrack(E::from_error_kind(input, ErrorKind::Token))
1274 }
1275 })
1276 }
1277
1278 /// Recognizes an unsigned 2 bytes integer
1279 ///
1280 /// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u16 integer,
1281 /// otherwise if `winnow::binary::Endianness::Little` parse a little endian u16 integer.
1282 ///
1283 /// *Complete version*: returns an error if there is not enough input data
1284 ///
1285 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1286 ///
1287 /// # Example
1288 ///
1289 /// ```rust
1290 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1291 /// # use winnow::prelude::*;
1292 /// # use winnow::error::Needed::Size;
1293 /// use winnow::binary::u16;
1294 ///
1295 /// let be_u16 = |s| {
1296 /// u16(winnow::binary::Endianness::Big).parse_peek(s)
1297 /// };
1298 ///
1299 /// assert_eq!(be_u16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0003)));
1300 /// assert_eq!(be_u16(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1301 ///
1302 /// let le_u16 = |s| {
1303 /// u16(winnow::binary::Endianness::Little).parse_peek(s)
1304 /// };
1305 ///
1306 /// assert_eq!(le_u16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0300)));
1307 /// assert_eq!(le_u16(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1308 /// ```
1309 ///
1310 /// ```rust
1311 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1312 /// # use winnow::prelude::*;
1313 /// # use winnow::error::Needed::Size;
1314 /// # use winnow::Partial;
1315 /// use winnow::binary::u16;
1316 ///
1317 /// let be_u16 = |s| {
1318 /// u16::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1319 /// };
1320 ///
1321 /// assert_eq!(be_u16(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0003)));
1322 /// assert_eq!(be_u16(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
1323 ///
1324 /// let le_u16 = |s| {
1325 /// u16::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1326 /// };
1327 ///
1328 /// assert_eq!(le_u16(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0300)));
1329 /// assert_eq!(le_u16(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
1330 /// ```
1331 #[inline(always)]
u16<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u16, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1332 pub fn u16<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u16, E>
1333 where
1334 I: StreamIsPartial,
1335 I: Stream<Token = u8>,
1336 <I as Stream>::Slice: AsBytes,
1337 {
1338 move |input: &mut I| {
1339 match endian {
1340 Endianness::Big => be_u16,
1341 Endianness::Little => le_u16,
1342 #[cfg(target_endian = "big")]
1343 Endianness::Native => be_u16,
1344 #[cfg(target_endian = "little")]
1345 Endianness::Native => le_u16,
1346 }
1347 }(input)
1348 }
1349
1350 /// Recognizes an unsigned 3 byte integer
1351 ///
1352 /// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u24 integer,
1353 /// otherwise if `winnow::binary::Endianness::Little` parse a little endian u24 integer.
1354 ///
1355 /// *Complete version*: returns an error if there is not enough input data
1356 ///
1357 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1358 ///
1359 /// # Example
1360 ///
1361 /// ```rust
1362 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1363 /// # use winnow::prelude::*;
1364 /// # use winnow::error::Needed::Size;
1365 /// use winnow::binary::u24;
1366 ///
1367 /// let be_u24 = |s| {
1368 /// u24(winnow::binary::Endianness::Big).parse_peek(s)
1369 /// };
1370 ///
1371 /// assert_eq!(be_u24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x000305)));
1372 /// assert_eq!(be_u24(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1373 ///
1374 /// let le_u24 = |s| {
1375 /// u24(winnow::binary::Endianness::Little).parse_peek(s)
1376 /// };
1377 ///
1378 /// assert_eq!(le_u24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x050300)));
1379 /// assert_eq!(le_u24(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1380 /// ```
1381 ///
1382 /// ```rust
1383 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1384 /// # use winnow::prelude::*;
1385 /// # use winnow::error::Needed::Size;
1386 /// # use winnow::Partial;
1387 /// use winnow::binary::u24;
1388 ///
1389 /// let be_u24 = |s| {
1390 /// u24::<_,InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1391 /// };
1392 ///
1393 /// assert_eq!(be_u24(Partial::new(&b"\x00\x03\x05abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x000305)));
1394 /// assert_eq!(be_u24(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2))));
1395 ///
1396 /// let le_u24 = |s| {
1397 /// u24::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1398 /// };
1399 ///
1400 /// assert_eq!(le_u24(Partial::new(&b"\x00\x03\x05abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x050300)));
1401 /// assert_eq!(le_u24(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2))));
1402 /// ```
1403 #[inline(always)]
u24<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1404 pub fn u24<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u32, E>
1405 where
1406 I: StreamIsPartial,
1407 I: Stream<Token = u8>,
1408 <I as Stream>::Slice: AsBytes,
1409 {
1410 move |input: &mut I| {
1411 match endian {
1412 Endianness::Big => be_u24,
1413 Endianness::Little => le_u24,
1414 #[cfg(target_endian = "big")]
1415 Endianness::Native => be_u24,
1416 #[cfg(target_endian = "little")]
1417 Endianness::Native => le_u24,
1418 }
1419 }(input)
1420 }
1421
1422 /// Recognizes an unsigned 4 byte integer
1423 ///
1424 /// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u32 integer,
1425 /// otherwise if `winnow::binary::Endianness::Little` parse a little endian u32 integer.
1426 ///
1427 /// *Complete version*: returns an error if there is not enough input data
1428 ///
1429 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1430 ///
1431 /// # Example
1432 ///
1433 /// ```rust
1434 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1435 /// # use winnow::prelude::*;
1436 /// # use winnow::error::Needed::Size;
1437 /// use winnow::binary::u32;
1438 ///
1439 /// let be_u32 = |s| {
1440 /// u32(winnow::binary::Endianness::Big).parse_peek(s)
1441 /// };
1442 ///
1443 /// assert_eq!(be_u32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00030507)));
1444 /// assert_eq!(be_u32(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1445 ///
1446 /// let le_u32 = |s| {
1447 /// u32(winnow::binary::Endianness::Little).parse_peek(s)
1448 /// };
1449 ///
1450 /// assert_eq!(le_u32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07050300)));
1451 /// assert_eq!(le_u32(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1452 /// ```
1453 ///
1454 /// ```rust
1455 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1456 /// # use winnow::prelude::*;
1457 /// # use winnow::error::Needed::Size;
1458 /// # use winnow::Partial;
1459 /// use winnow::binary::u32;
1460 ///
1461 /// let be_u32 = |s| {
1462 /// u32::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1463 /// };
1464 ///
1465 /// assert_eq!(be_u32(Partial::new(&b"\x00\x03\x05\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x00030507)));
1466 /// assert_eq!(be_u32(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3))));
1467 ///
1468 /// let le_u32 = |s| {
1469 /// u32::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1470 /// };
1471 ///
1472 /// assert_eq!(le_u32(Partial::new(&b"\x00\x03\x05\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x07050300)));
1473 /// assert_eq!(le_u32(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3))));
1474 /// ```
1475 #[inline(always)]
u32<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1476 pub fn u32<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u32, E>
1477 where
1478 I: StreamIsPartial,
1479 I: Stream<Token = u8>,
1480 <I as Stream>::Slice: AsBytes,
1481 {
1482 move |input: &mut I| {
1483 match endian {
1484 Endianness::Big => be_u32,
1485 Endianness::Little => le_u32,
1486 #[cfg(target_endian = "big")]
1487 Endianness::Native => be_u32,
1488 #[cfg(target_endian = "little")]
1489 Endianness::Native => le_u32,
1490 }
1491 }(input)
1492 }
1493
1494 /// Recognizes an unsigned 8 byte integer
1495 ///
1496 /// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u64 integer,
1497 /// otherwise if `winnow::binary::Endianness::Little` parse a little endian u64 integer.
1498 ///
1499 /// *Complete version*: returns an error if there is not enough input data
1500 ///
1501 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1502 ///
1503 /// # Example
1504 ///
1505 /// ```rust
1506 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1507 /// # use winnow::prelude::*;
1508 /// # use winnow::error::Needed::Size;
1509 /// use winnow::binary::u64;
1510 ///
1511 /// let be_u64 = |s| {
1512 /// u64(winnow::binary::Endianness::Big).parse_peek(s)
1513 /// };
1514 ///
1515 /// assert_eq!(be_u64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0001020304050607)));
1516 /// assert_eq!(be_u64(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1517 ///
1518 /// let le_u64 = |s| {
1519 /// u64(winnow::binary::Endianness::Little).parse_peek(s)
1520 /// };
1521 ///
1522 /// assert_eq!(le_u64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0706050403020100)));
1523 /// assert_eq!(le_u64(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1524 /// ```
1525 ///
1526 /// ```rust
1527 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1528 /// # use winnow::prelude::*;
1529 /// # use winnow::error::Needed::Size;
1530 /// # use winnow::Partial;
1531 /// use winnow::binary::u64;
1532 ///
1533 /// let be_u64 = |s| {
1534 /// u64::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1535 /// };
1536 ///
1537 /// assert_eq!(be_u64(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0001020304050607)));
1538 /// assert_eq!(be_u64(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7))));
1539 ///
1540 /// let le_u64 = |s| {
1541 /// u64::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1542 /// };
1543 ///
1544 /// assert_eq!(le_u64(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0706050403020100)));
1545 /// assert_eq!(le_u64(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7))));
1546 /// ```
1547 #[inline(always)]
u64<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u64, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1548 pub fn u64<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u64, E>
1549 where
1550 I: StreamIsPartial,
1551 I: Stream<Token = u8>,
1552 <I as Stream>::Slice: AsBytes,
1553 {
1554 move |input: &mut I| {
1555 match endian {
1556 Endianness::Big => be_u64,
1557 Endianness::Little => le_u64,
1558 #[cfg(target_endian = "big")]
1559 Endianness::Native => be_u64,
1560 #[cfg(target_endian = "little")]
1561 Endianness::Native => le_u64,
1562 }
1563 }(input)
1564 }
1565
1566 /// Recognizes an unsigned 16 byte integer
1567 ///
1568 /// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u128 integer,
1569 /// otherwise if `winnow::binary::Endianness::Little` parse a little endian u128 integer.
1570 ///
1571 /// *Complete version*: returns an error if there is not enough input data
1572 ///
1573 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1574 ///
1575 /// # Example
1576 ///
1577 /// ```rust
1578 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1579 /// # use winnow::prelude::*;
1580 /// # use winnow::error::Needed::Size;
1581 /// use winnow::binary::u128;
1582 ///
1583 /// let be_u128 = |s| {
1584 /// u128(winnow::binary::Endianness::Big).parse_peek(s)
1585 /// };
1586 ///
1587 /// assert_eq!(be_u128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00010203040506070001020304050607)));
1588 /// assert_eq!(be_u128(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1589 ///
1590 /// let le_u128 = |s| {
1591 /// u128(winnow::binary::Endianness::Little).parse_peek(s)
1592 /// };
1593 ///
1594 /// assert_eq!(le_u128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07060504030201000706050403020100)));
1595 /// assert_eq!(le_u128(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1596 /// ```
1597 ///
1598 /// ```rust
1599 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1600 /// # use winnow::prelude::*;
1601 /// # use winnow::error::Needed::Size;
1602 /// # use winnow::Partial;
1603 /// use winnow::binary::u128;
1604 ///
1605 /// let be_u128 = |s| {
1606 /// u128::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1607 /// };
1608 ///
1609 /// assert_eq!(be_u128(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x00010203040506070001020304050607)));
1610 /// assert_eq!(be_u128(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15))));
1611 ///
1612 /// let le_u128 = |s| {
1613 /// u128::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1614 /// };
1615 ///
1616 /// assert_eq!(le_u128(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x07060504030201000706050403020100)));
1617 /// assert_eq!(le_u128(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15))));
1618 /// ```
1619 #[inline(always)]
u128<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u128, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1620 pub fn u128<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u128, E>
1621 where
1622 I: StreamIsPartial,
1623 I: Stream<Token = u8>,
1624 <I as Stream>::Slice: AsBytes,
1625 {
1626 move |input: &mut I| {
1627 match endian {
1628 Endianness::Big => be_u128,
1629 Endianness::Little => le_u128,
1630 #[cfg(target_endian = "big")]
1631 Endianness::Native => be_u128,
1632 #[cfg(target_endian = "little")]
1633 Endianness::Native => le_u128,
1634 }
1635 }(input)
1636 }
1637
1638 /// Recognizes a signed 1 byte integer
1639 ///
1640 /// **Note:** that endianness does not apply to 1 byte numbers.
1641 ///
1642 /// *Complete version*: returns an error if there is not enough input data
1643 ///
1644 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1645 ///
1646 /// # Example
1647 ///
1648 /// ```rust
1649 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1650 /// # use winnow::prelude::*;
1651 /// # use winnow::error::Needed::Size;
1652 /// use winnow::binary::i8;
1653 ///
1654 /// fn parser(s: &[u8]) -> IResult<&[u8], i8> {
1655 /// i8.parse_peek(s)
1656 /// }
1657 ///
1658 /// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"\x03abcefg"[..], 0x00)));
1659 /// assert_eq!(parser(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&[][..], ErrorKind::Token))));
1660 /// ```
1661 ///
1662 /// ```rust
1663 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1664 /// # use winnow::prelude::*;
1665 /// # use winnow::error::Needed::Size;
1666 /// # use winnow::Partial;
1667 /// use winnow::binary::i8;
1668 ///
1669 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i8> {
1670 /// i8.parse_peek(s)
1671 /// }
1672 ///
1673 /// assert_eq!(parser(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"\x03abcefg"[..]), 0x00)));
1674 /// assert_eq!(parser(Partial::new(&b""[..])), Err(ErrMode::Incomplete(Needed::new(1))));
1675 /// ```
1676 #[inline(always)]
i8<I, E: ParserError<I>>(input: &mut I) -> PResult<i8, E> where I: StreamIsPartial, I: Stream<Token = u8>,1677 pub fn i8<I, E: ParserError<I>>(input: &mut I) -> PResult<i8, E>
1678 where
1679 I: StreamIsPartial,
1680 I: Stream<Token = u8>,
1681 {
1682 trace("i8", move |input: &mut I| {
1683 if <I as StreamIsPartial>::is_partial_supported() {
1684 u8_::<_, _, true>(input)
1685 } else {
1686 u8_::<_, _, false>(input)
1687 }
1688 .map(|n| n as i8)
1689 })
1690 .parse_next(input)
1691 }
1692
1693 /// Recognizes a signed 2 byte integer
1694 ///
1695 /// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i16 integer,
1696 /// otherwise if `winnow::binary::Endianness::Little` parse a little endian i16 integer.
1697 ///
1698 /// *Complete version*: returns an error if there is not enough input data
1699 ///
1700 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1701 ///
1702 /// # Example
1703 ///
1704 /// ```rust
1705 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1706 /// # use winnow::prelude::*;
1707 /// # use winnow::error::Needed::Size;
1708 /// use winnow::binary::i16;
1709 ///
1710 /// let be_i16 = |s| {
1711 /// i16(winnow::binary::Endianness::Big).parse_peek(s)
1712 /// };
1713 ///
1714 /// assert_eq!(be_i16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0003)));
1715 /// assert_eq!(be_i16(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1716 ///
1717 /// let le_i16 = |s| {
1718 /// i16(winnow::binary::Endianness::Little).parse_peek(s)
1719 /// };
1720 ///
1721 /// assert_eq!(le_i16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0300)));
1722 /// assert_eq!(le_i16(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1723 /// ```
1724 ///
1725 /// ```rust
1726 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1727 /// # use winnow::prelude::*;
1728 /// # use winnow::error::Needed::Size;
1729 /// # use winnow::Partial;
1730 /// use winnow::binary::i16;
1731 ///
1732 /// let be_i16 = |s| {
1733 /// i16::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1734 /// };
1735 ///
1736 /// assert_eq!(be_i16(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0003)));
1737 /// assert_eq!(be_i16(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
1738 ///
1739 /// let le_i16 = |s| {
1740 /// i16::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1741 /// };
1742 ///
1743 /// assert_eq!(le_i16(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0300)));
1744 /// assert_eq!(le_i16(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
1745 /// ```
1746 #[inline(always)]
i16<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i16, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1747 pub fn i16<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i16, E>
1748 where
1749 I: StreamIsPartial,
1750 I: Stream<Token = u8>,
1751 <I as Stream>::Slice: AsBytes,
1752 {
1753 move |input: &mut I| {
1754 match endian {
1755 Endianness::Big => be_i16,
1756 Endianness::Little => le_i16,
1757 #[cfg(target_endian = "big")]
1758 Endianness::Native => be_i16,
1759 #[cfg(target_endian = "little")]
1760 Endianness::Native => le_i16,
1761 }
1762 }(input)
1763 }
1764
1765 /// Recognizes a signed 3 byte integer
1766 ///
1767 /// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i24 integer,
1768 /// otherwise if `winnow::binary::Endianness::Little` parse a little endian i24 integer.
1769 ///
1770 /// *Complete version*: returns an error if there is not enough input data
1771 ///
1772 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1773 ///
1774 /// # Example
1775 ///
1776 /// ```rust
1777 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1778 /// # use winnow::prelude::*;
1779 /// # use winnow::error::Needed::Size;
1780 /// use winnow::binary::i24;
1781 ///
1782 /// let be_i24 = |s| {
1783 /// i24(winnow::binary::Endianness::Big).parse_peek(s)
1784 /// };
1785 ///
1786 /// assert_eq!(be_i24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x000305)));
1787 /// assert_eq!(be_i24(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1788 ///
1789 /// let le_i24 = |s| {
1790 /// i24(winnow::binary::Endianness::Little).parse_peek(s)
1791 /// };
1792 ///
1793 /// assert_eq!(le_i24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x050300)));
1794 /// assert_eq!(le_i24(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1795 /// ```
1796 ///
1797 /// ```rust
1798 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1799 /// # use winnow::prelude::*;
1800 /// # use winnow::error::Needed::Size;
1801 /// # use winnow::Partial;
1802 /// use winnow::binary::i24;
1803 ///
1804 /// let be_i24 = |s| {
1805 /// i24::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1806 /// };
1807 ///
1808 /// assert_eq!(be_i24(Partial::new(&b"\x00\x03\x05abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x000305)));
1809 /// assert_eq!(be_i24(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2))));
1810 ///
1811 /// let le_i24 = |s| {
1812 /// i24::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1813 /// };
1814 ///
1815 /// assert_eq!(le_i24(Partial::new(&b"\x00\x03\x05abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x050300)));
1816 /// assert_eq!(le_i24(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2))));
1817 /// ```
1818 #[inline(always)]
i24<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1819 pub fn i24<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i32, E>
1820 where
1821 I: StreamIsPartial,
1822 I: Stream<Token = u8>,
1823 <I as Stream>::Slice: AsBytes,
1824 {
1825 move |input: &mut I| {
1826 match endian {
1827 Endianness::Big => be_i24,
1828 Endianness::Little => le_i24,
1829 #[cfg(target_endian = "big")]
1830 Endianness::Native => be_i24,
1831 #[cfg(target_endian = "little")]
1832 Endianness::Native => le_i24,
1833 }
1834 }(input)
1835 }
1836
1837 /// Recognizes a signed 4 byte integer
1838 ///
1839 /// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i32 integer,
1840 /// otherwise if `winnow::binary::Endianness::Little` parse a little endian i32 integer.
1841 ///
1842 /// *Complete version*: returns an error if there is not enough input data
1843 ///
1844 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1845 ///
1846 /// # Example
1847 ///
1848 /// ```rust
1849 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1850 /// # use winnow::prelude::*;
1851 /// # use winnow::error::Needed::Size;
1852 /// use winnow::binary::i32;
1853 ///
1854 /// let be_i32 = |s| {
1855 /// i32(winnow::binary::Endianness::Big).parse_peek(s)
1856 /// };
1857 ///
1858 /// assert_eq!(be_i32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00030507)));
1859 /// assert_eq!(be_i32(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1860 ///
1861 /// let le_i32 = |s| {
1862 /// i32(winnow::binary::Endianness::Little).parse_peek(s)
1863 /// };
1864 ///
1865 /// assert_eq!(le_i32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07050300)));
1866 /// assert_eq!(le_i32(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1867 /// ```
1868 ///
1869 /// ```rust
1870 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1871 /// # use winnow::prelude::*;
1872 /// # use winnow::error::Needed::Size;
1873 /// # use winnow::Partial;
1874 /// use winnow::binary::i32;
1875 ///
1876 /// let be_i32 = |s| {
1877 /// i32::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1878 /// };
1879 ///
1880 /// assert_eq!(be_i32(Partial::new(&b"\x00\x03\x05\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x00030507)));
1881 /// assert_eq!(be_i32(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3))));
1882 ///
1883 /// let le_i32 = |s| {
1884 /// i32::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1885 /// };
1886 ///
1887 /// assert_eq!(le_i32(Partial::new(&b"\x00\x03\x05\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x07050300)));
1888 /// assert_eq!(le_i32(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3))));
1889 /// ```
1890 #[inline(always)]
i32<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1891 pub fn i32<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i32, E>
1892 where
1893 I: StreamIsPartial,
1894 I: Stream<Token = u8>,
1895 <I as Stream>::Slice: AsBytes,
1896 {
1897 move |input: &mut I| {
1898 match endian {
1899 Endianness::Big => be_i32,
1900 Endianness::Little => le_i32,
1901 #[cfg(target_endian = "big")]
1902 Endianness::Native => be_i32,
1903 #[cfg(target_endian = "little")]
1904 Endianness::Native => le_i32,
1905 }
1906 }(input)
1907 }
1908
1909 /// Recognizes a signed 8 byte integer
1910 ///
1911 /// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i64 integer,
1912 /// otherwise if `winnow::binary::Endianness::Little` parse a little endian i64 integer.
1913 ///
1914 /// *Complete version*: returns an error if there is not enough input data
1915 ///
1916 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1917 ///
1918 /// # Example
1919 ///
1920 /// ```rust
1921 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1922 /// # use winnow::prelude::*;
1923 /// # use winnow::error::Needed::Size;
1924 /// use winnow::binary::i64;
1925 ///
1926 /// let be_i64 = |s| {
1927 /// i64(winnow::binary::Endianness::Big).parse_peek(s)
1928 /// };
1929 ///
1930 /// assert_eq!(be_i64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0001020304050607)));
1931 /// assert_eq!(be_i64(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1932 ///
1933 /// let le_i64 = |s| {
1934 /// i64(winnow::binary::Endianness::Little).parse_peek(s)
1935 /// };
1936 ///
1937 /// assert_eq!(le_i64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0706050403020100)));
1938 /// assert_eq!(le_i64(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1939 /// ```
1940 ///
1941 /// ```rust
1942 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1943 /// # use winnow::prelude::*;
1944 /// # use winnow::error::Needed::Size;
1945 /// # use winnow::Partial;
1946 /// use winnow::binary::i64;
1947 ///
1948 /// let be_i64 = |s| {
1949 /// i64::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1950 /// };
1951 ///
1952 /// assert_eq!(be_i64(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0001020304050607)));
1953 /// assert_eq!(be_i64(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7))));
1954 ///
1955 /// let le_i64 = |s| {
1956 /// i64::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1957 /// };
1958 ///
1959 /// assert_eq!(le_i64(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0706050403020100)));
1960 /// assert_eq!(le_i64(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7))));
1961 /// ```
1962 #[inline(always)]
i64<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i64, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,1963 pub fn i64<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i64, E>
1964 where
1965 I: StreamIsPartial,
1966 I: Stream<Token = u8>,
1967 <I as Stream>::Slice: AsBytes,
1968 {
1969 move |input: &mut I| {
1970 match endian {
1971 Endianness::Big => be_i64,
1972 Endianness::Little => le_i64,
1973 #[cfg(target_endian = "big")]
1974 Endianness::Native => be_i64,
1975 #[cfg(target_endian = "little")]
1976 Endianness::Native => le_i64,
1977 }
1978 }(input)
1979 }
1980
1981 /// Recognizes a signed 16 byte integer
1982 ///
1983 /// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i128 integer,
1984 /// otherwise if `winnow::binary::Endianness::Little` parse a little endian i128 integer.
1985 ///
1986 /// *Complete version*: returns an error if there is not enough input data
1987 ///
1988 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1989 ///
1990 /// # Example
1991 ///
1992 /// ```rust
1993 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1994 /// # use winnow::prelude::*;
1995 /// # use winnow::error::Needed::Size;
1996 /// use winnow::binary::i128;
1997 ///
1998 /// let be_i128 = |s| {
1999 /// i128(winnow::binary::Endianness::Big).parse_peek(s)
2000 /// };
2001 ///
2002 /// assert_eq!(be_i128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00010203040506070001020304050607)));
2003 /// assert_eq!(be_i128(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
2004 ///
2005 /// let le_i128 = |s| {
2006 /// i128(winnow::binary::Endianness::Little).parse_peek(s)
2007 /// };
2008 ///
2009 /// assert_eq!(le_i128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07060504030201000706050403020100)));
2010 /// assert_eq!(le_i128(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
2011 /// ```
2012 ///
2013 /// ```rust
2014 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2015 /// # use winnow::prelude::*;
2016 /// # use winnow::error::Needed::Size;
2017 /// # use winnow::Partial;
2018 /// use winnow::binary::i128;
2019 ///
2020 /// let be_i128 = |s| {
2021 /// i128::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
2022 /// };
2023 ///
2024 /// assert_eq!(be_i128(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x00010203040506070001020304050607)));
2025 /// assert_eq!(be_i128(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15))));
2026 ///
2027 /// let le_i128 = |s| {
2028 /// i128::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
2029 /// };
2030 ///
2031 /// assert_eq!(le_i128(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x07060504030201000706050403020100)));
2032 /// assert_eq!(le_i128(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15))));
2033 /// ```
2034 #[inline(always)]
i128<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i128, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,2035 pub fn i128<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i128, E>
2036 where
2037 I: StreamIsPartial,
2038 I: Stream<Token = u8>,
2039 <I as Stream>::Slice: AsBytes,
2040 {
2041 move |input: &mut I| {
2042 match endian {
2043 Endianness::Big => be_i128,
2044 Endianness::Little => le_i128,
2045 #[cfg(target_endian = "big")]
2046 Endianness::Native => be_i128,
2047 #[cfg(target_endian = "little")]
2048 Endianness::Native => le_i128,
2049 }
2050 }(input)
2051 }
2052
2053 /// Recognizes a big endian 4 bytes floating point number.
2054 ///
2055 /// *Complete version*: Returns an error if there is not enough input data.
2056 ///
2057 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2058 ///
2059 /// # Example
2060 ///
2061 /// ```rust
2062 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2063 /// # use winnow::prelude::*;
2064 /// # use winnow::prelude::*;
2065 /// # use winnow::error::Needed::Size;
2066 /// use winnow::binary::be_f32;
2067 ///
2068 /// fn parser(s: &[u8]) -> IResult<&[u8], f32> {
2069 /// be_f32.parse_peek(s)
2070 /// }
2071 ///
2072 /// assert_eq!(parser(&[0x41, 0x48, 0x00, 0x00][..]), Ok((&b""[..], 12.5)));
2073 /// assert_eq!(parser(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2074 /// ```
2075 ///
2076 /// ```rust
2077 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2078 /// # use winnow::prelude::*;
2079 /// # use winnow::Partial;
2080 /// use winnow::binary::be_f32;
2081 ///
2082 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, f32> {
2083 /// be_f32.parse_peek(s)
2084 /// }
2085 ///
2086 /// assert_eq!(parser(Partial::new(&[0x40, 0x29, 0x00, 0x00][..])), Ok((Partial::new(&b""[..]), 2.640625)));
2087 /// assert_eq!(parser(Partial::new(&[0x01][..])), Err(ErrMode::Incomplete(Needed::new(3))));
2088 /// ```
2089 #[inline(always)]
be_f32<I, E: ParserError<I>>(input: &mut I) -> PResult<f32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,2090 pub fn be_f32<I, E: ParserError<I>>(input: &mut I) -> PResult<f32, E>
2091 where
2092 I: StreamIsPartial,
2093 I: Stream<Token = u8>,
2094 <I as Stream>::Slice: AsBytes,
2095 {
2096 trace("be_f32", move |input: &mut I| {
2097 be_uint::<_, u32, _>(input, 4).map(f32::from_bits)
2098 })
2099 .parse_next(input)
2100 }
2101
2102 /// Recognizes a big endian 8 bytes floating point number.
2103 ///
2104 /// *Complete version*: Returns an error if there is not enough input data.
2105 ///
2106 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2107 ///
2108 /// # Example
2109 ///
2110 /// ```rust
2111 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2112 /// # use winnow::prelude::*;
2113 /// # use winnow::error::Needed::Size;
2114 /// use winnow::binary::be_f64;
2115 ///
2116 /// fn parser(s: &[u8]) -> IResult<&[u8], f64> {
2117 /// be_f64.parse_peek(s)
2118 /// }
2119 ///
2120 /// assert_eq!(parser(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 12.5)));
2121 /// assert_eq!(parser(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2122 /// ```
2123 ///
2124 /// ```rust
2125 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2126 /// # use winnow::prelude::*;
2127 /// # use winnow::Partial;
2128 /// use winnow::binary::be_f64;
2129 ///
2130 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, f64> {
2131 /// be_f64::<_, InputError<_>>.parse_peek(s)
2132 /// }
2133 ///
2134 /// assert_eq!(parser(Partial::new(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..])), Ok((Partial::new(&b""[..]), 12.5)));
2135 /// assert_eq!(parser(Partial::new(&[0x01][..])), Err(ErrMode::Incomplete(Needed::new(7))));
2136 /// ```
2137 #[inline(always)]
be_f64<I, E: ParserError<I>>(input: &mut I) -> PResult<f64, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,2138 pub fn be_f64<I, E: ParserError<I>>(input: &mut I) -> PResult<f64, E>
2139 where
2140 I: StreamIsPartial,
2141 I: Stream<Token = u8>,
2142 <I as Stream>::Slice: AsBytes,
2143 {
2144 trace("be_f64", move |input: &mut I| {
2145 be_uint::<_, u64, _>(input, 8).map(f64::from_bits)
2146 })
2147 .parse_next(input)
2148 }
2149
2150 /// Recognizes a little endian 4 bytes floating point number.
2151 ///
2152 /// *Complete version*: Returns an error if there is not enough input data.
2153 ///
2154 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2155 ///
2156 /// # Example
2157 ///
2158 /// ```rust
2159 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2160 /// # use winnow::prelude::*;
2161 /// # use winnow::error::Needed::Size;
2162 /// use winnow::binary::le_f32;
2163 ///
2164 /// fn parser(s: &[u8]) -> IResult<&[u8], f32> {
2165 /// le_f32.parse_peek(s)
2166 /// }
2167 ///
2168 /// assert_eq!(parser(&[0x00, 0x00, 0x48, 0x41][..]), Ok((&b""[..], 12.5)));
2169 /// assert_eq!(parser(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2170 /// ```
2171 ///
2172 /// ```rust
2173 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2174 /// # use winnow::prelude::*;
2175 /// # use winnow::Partial;
2176 /// use winnow::binary::le_f32;
2177 ///
2178 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, f32> {
2179 /// le_f32::<_, InputError<_>>.parse_peek(s)
2180 /// }
2181 ///
2182 /// assert_eq!(parser(Partial::new(&[0x00, 0x00, 0x48, 0x41][..])), Ok((Partial::new(&b""[..]), 12.5)));
2183 /// assert_eq!(parser(Partial::new(&[0x01][..])), Err(ErrMode::Incomplete(Needed::new(3))));
2184 /// ```
2185 #[inline(always)]
le_f32<I, E: ParserError<I>>(input: &mut I) -> PResult<f32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,2186 pub fn le_f32<I, E: ParserError<I>>(input: &mut I) -> PResult<f32, E>
2187 where
2188 I: StreamIsPartial,
2189 I: Stream<Token = u8>,
2190 <I as Stream>::Slice: AsBytes,
2191 {
2192 trace("le_f32", move |input: &mut I| {
2193 le_uint::<_, u32, _>(input, 4).map(f32::from_bits)
2194 })
2195 .parse_next(input)
2196 }
2197
2198 /// Recognizes a little endian 8 bytes floating point number.
2199 ///
2200 /// *Complete version*: Returns an error if there is not enough input data.
2201 ///
2202 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2203 ///
2204 /// # Example
2205 ///
2206 /// ```rust
2207 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2208 /// # use winnow::prelude::*;
2209 /// # use winnow::error::Needed::Size;
2210 /// use winnow::binary::le_f64;
2211 ///
2212 /// fn parser(s: &[u8]) -> IResult<&[u8], f64> {
2213 /// le_f64.parse_peek(s)
2214 /// }
2215 ///
2216 /// assert_eq!(parser(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40][..]), Ok((&b""[..], 12.5)));
2217 /// assert_eq!(parser(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2218 /// ```
2219 ///
2220 /// ```rust
2221 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2222 /// # use winnow::prelude::*;
2223 /// # use winnow::Partial;
2224 /// use winnow::binary::le_f64;
2225 ///
2226 /// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, f64> {
2227 /// le_f64::<_, InputError<_>>.parse_peek(s)
2228 /// }
2229 ///
2230 /// assert_eq!(parser(Partial::new(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41][..])), Ok((Partial::new(&b""[..]), 3145728.0)));
2231 /// assert_eq!(parser(Partial::new(&[0x01][..])), Err(ErrMode::Incomplete(Needed::new(7))));
2232 /// ```
2233 #[inline(always)]
le_f64<I, E: ParserError<I>>(input: &mut I) -> PResult<f64, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,2234 pub fn le_f64<I, E: ParserError<I>>(input: &mut I) -> PResult<f64, E>
2235 where
2236 I: StreamIsPartial,
2237 I: Stream<Token = u8>,
2238 <I as Stream>::Slice: AsBytes,
2239 {
2240 trace("be_f64", move |input: &mut I| {
2241 le_uint::<_, u64, _>(input, 8).map(f64::from_bits)
2242 })
2243 .parse_next(input)
2244 }
2245
2246 /// Recognizes a 4 byte floating point number
2247 ///
2248 /// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian f32 float,
2249 /// otherwise if `winnow::binary::Endianness::Little` parse a little endian f32 float.
2250 ///
2251 /// *Complete version*: returns an error if there is not enough input data
2252 ///
2253 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2254 ///
2255 /// # Example
2256 ///
2257 /// ```rust
2258 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2259 /// # use winnow::prelude::*;
2260 /// # use winnow::error::Needed::Size;
2261 /// use winnow::binary::f32;
2262 ///
2263 /// let be_f32 = |s| {
2264 /// f32(winnow::binary::Endianness::Big).parse_peek(s)
2265 /// };
2266 ///
2267 /// assert_eq!(be_f32(&[0x41, 0x48, 0x00, 0x00][..]), Ok((&b""[..], 12.5)));
2268 /// assert_eq!(be_f32(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2269 ///
2270 /// let le_f32 = |s| {
2271 /// f32(winnow::binary::Endianness::Little).parse_peek(s)
2272 /// };
2273 ///
2274 /// assert_eq!(le_f32(&[0x00, 0x00, 0x48, 0x41][..]), Ok((&b""[..], 12.5)));
2275 /// assert_eq!(le_f32(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2276 /// ```
2277 ///
2278 /// ```rust
2279 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2280 /// # use winnow::prelude::*;
2281 /// # use winnow::error::Needed::Size;
2282 /// # use winnow::Partial;
2283 /// use winnow::binary::f32;
2284 ///
2285 /// let be_f32 = |s| {
2286 /// f32::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
2287 /// };
2288 ///
2289 /// assert_eq!(be_f32(Partial::new(&[0x41, 0x48, 0x00, 0x00][..])), Ok((Partial::new(&b""[..]), 12.5)));
2290 /// assert_eq!(be_f32(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
2291 ///
2292 /// let le_f32 = |s| {
2293 /// f32::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
2294 /// };
2295 ///
2296 /// assert_eq!(le_f32(Partial::new(&[0x00, 0x00, 0x48, 0x41][..])), Ok((Partial::new(&b""[..]), 12.5)));
2297 /// assert_eq!(le_f32(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
2298 /// ```
2299 #[inline(always)]
f32<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, f32, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,2300 pub fn f32<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, f32, E>
2301 where
2302 I: StreamIsPartial,
2303 I: Stream<Token = u8>,
2304 <I as Stream>::Slice: AsBytes,
2305 {
2306 move |input: &mut I| {
2307 match endian {
2308 Endianness::Big => be_f32,
2309 Endianness::Little => le_f32,
2310 #[cfg(target_endian = "big")]
2311 Endianness::Native => be_f32,
2312 #[cfg(target_endian = "little")]
2313 Endianness::Native => le_f32,
2314 }
2315 }(input)
2316 }
2317
2318 /// Recognizes an 8 byte floating point number
2319 ///
2320 /// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian f64 float,
2321 /// otherwise if `winnow::binary::Endianness::Little` parse a little endian f64 float.
2322 ///
2323 /// *Complete version*: returns an error if there is not enough input data
2324 ///
2325 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2326 ///
2327 /// # Example
2328 ///
2329 /// ```rust
2330 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2331 /// # use winnow::prelude::*;
2332 /// # use winnow::error::Needed::Size;
2333 /// use winnow::binary::f64;
2334 ///
2335 /// let be_f64 = |s| {
2336 /// f64(winnow::binary::Endianness::Big).parse_peek(s)
2337 /// };
2338 ///
2339 /// assert_eq!(be_f64(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 12.5)));
2340 /// assert_eq!(be_f64(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2341 ///
2342 /// let le_f64 = |s| {
2343 /// f64(winnow::binary::Endianness::Little).parse_peek(s)
2344 /// };
2345 ///
2346 /// assert_eq!(le_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40][..]), Ok((&b""[..], 12.5)));
2347 /// assert_eq!(le_f64(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2348 /// ```
2349 ///
2350 /// ```rust
2351 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2352 /// # use winnow::prelude::*;
2353 /// # use winnow::error::Needed::Size;
2354 /// # use winnow::Partial;
2355 /// use winnow::binary::f64;
2356 ///
2357 /// let be_f64 = |s| {
2358 /// f64::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
2359 /// };
2360 ///
2361 /// assert_eq!(be_f64(Partial::new(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..])), Ok((Partial::new(&b""[..]), 12.5)));
2362 /// assert_eq!(be_f64(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(5))));
2363 ///
2364 /// let le_f64 = |s| {
2365 /// f64::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
2366 /// };
2367 ///
2368 /// assert_eq!(le_f64(Partial::new(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40][..])), Ok((Partial::new(&b""[..]), 12.5)));
2369 /// assert_eq!(le_f64(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(5))));
2370 /// ```
2371 #[inline(always)]
f64<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, f64, E> where I: StreamIsPartial, I: Stream<Token = u8>, <I as Stream>::Slice: AsBytes,2372 pub fn f64<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, f64, E>
2373 where
2374 I: StreamIsPartial,
2375 I: Stream<Token = u8>,
2376 <I as Stream>::Slice: AsBytes,
2377 {
2378 move |input: &mut I| {
2379 match endian {
2380 Endianness::Big => be_f64,
2381 Endianness::Little => le_f64,
2382 #[cfg(target_endian = "big")]
2383 Endianness::Native => be_f64,
2384 #[cfg(target_endian = "little")]
2385 Endianness::Native => le_f64,
2386 }
2387 }(input)
2388 }
2389
2390 /// Get a length-prefixed slice ([TLV](https://en.wikipedia.org/wiki/Type-length-value))
2391 ///
2392 /// To apply a parser to the returned slice, see [`length_and_then`].
2393 ///
2394 /// If the count is for something besides tokens, see [`length_repeat`].
2395 ///
2396 /// *Complete version*: Returns an error if there is not enough input data.
2397 ///
2398 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2399 ///
2400 /// # Arguments
2401 /// * `f` The parser to apply.
2402 ///
2403 /// # Example
2404 ///
2405 /// ```rust
2406 /// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed, stream::Partial};
2407 /// # use winnow::prelude::*;
2408 /// use winnow::Bytes;
2409 /// use winnow::binary::be_u16;
2410 /// use winnow::binary::length_take;
2411 /// use winnow::token::tag;
2412 ///
2413 /// type Stream<'i> = Partial<&'i Bytes>;
2414 ///
2415 /// fn stream(b: &[u8]) -> Stream<'_> {
2416 /// Partial::new(Bytes::new(b))
2417 /// }
2418 ///
2419 /// fn parser(s: Stream<'_>) -> IResult<Stream<'_>, &[u8]> {
2420 /// length_take(be_u16).parse_peek(s)
2421 /// }
2422 ///
2423 /// assert_eq!(parser(stream(b"\x00\x03abcefg")), Ok((stream(&b"efg"[..]), &b"abc"[..])));
2424 /// assert_eq!(parser(stream(b"\x00\x03a")), Err(ErrMode::Incomplete(Needed::new(2))));
2425 /// ```
length_take<I, N, E, F>(mut f: F) -> impl Parser<I, <I as Stream>::Slice, E> where I: StreamIsPartial, I: Stream, N: ToUsize, F: Parser<I, N, E>, E: ParserError<I>,2426 pub fn length_take<I, N, E, F>(mut f: F) -> impl Parser<I, <I as Stream>::Slice, E>
2427 where
2428 I: StreamIsPartial,
2429 I: Stream,
2430 N: ToUsize,
2431 F: Parser<I, N, E>,
2432 E: ParserError<I>,
2433 {
2434 trace("length_take", move |i: &mut I| {
2435 let length = f.parse_next(i)?;
2436
2437 crate::token::take(length).parse_next(i)
2438 })
2439 }
2440
2441 /// Deprecated since 0.5.27, replaced with [`length_take`]
2442 #[deprecated(since = "0.5.27", note = "Replaced with `length_take`")]
length_data<I, N, E, F>(f: F) -> impl Parser<I, <I as Stream>::Slice, E> where I: StreamIsPartial, I: Stream, N: ToUsize, F: Parser<I, N, E>, E: ParserError<I>,2443 pub fn length_data<I, N, E, F>(f: F) -> impl Parser<I, <I as Stream>::Slice, E>
2444 where
2445 I: StreamIsPartial,
2446 I: Stream,
2447 N: ToUsize,
2448 F: Parser<I, N, E>,
2449 E: ParserError<I>,
2450 {
2451 length_take(f)
2452 }
2453
2454 /// Parse a length-prefixed slice ([TLV](https://en.wikipedia.org/wiki/Type-length-value))
2455 ///
2456 /// *Complete version*: Returns an error if there is not enough input data.
2457 ///
2458 /// *Partial version*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2459 ///
2460 /// # Arguments
2461 /// * `f` The parser to apply.
2462 /// * `g` The parser to apply on the subslice.
2463 ///
2464 /// # Example
2465 ///
2466 /// ```rust
2467 /// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed, stream::{Partial, StreamIsPartial}};
2468 /// # use winnow::prelude::*;
2469 /// use winnow::Bytes;
2470 /// use winnow::binary::be_u16;
2471 /// use winnow::binary::length_and_then;
2472 /// use winnow::token::tag;
2473 ///
2474 /// type Stream<'i> = Partial<&'i Bytes>;
2475 ///
2476 /// fn stream(b: &[u8]) -> Stream<'_> {
2477 /// Partial::new(Bytes::new(b))
2478 /// }
2479 ///
2480 /// fn complete_stream(b: &[u8]) -> Stream<'_> {
2481 /// let mut p = Partial::new(Bytes::new(b));
2482 /// let _ = p.complete();
2483 /// p
2484 /// }
2485 ///
2486 /// fn parser(s: Stream<'_>) -> IResult<Stream<'_>, &[u8]> {
2487 /// length_and_then(be_u16, "abc").parse_peek(s)
2488 /// }
2489 ///
2490 /// assert_eq!(parser(stream(b"\x00\x03abcefg")), Ok((stream(&b"efg"[..]), &b"abc"[..])));
2491 /// assert_eq!(parser(stream(b"\x00\x03123123")), Err(ErrMode::Backtrack(InputError::new(complete_stream(&b"123"[..]), ErrorKind::Tag))));
2492 /// assert_eq!(parser(stream(b"\x00\x03a")), Err(ErrMode::Incomplete(Needed::new(2))));
2493 /// ```
length_and_then<I, O, N, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, O, E> where I: StreamIsPartial, I: Stream + UpdateSlice + Clone, N: ToUsize, F: Parser<I, N, E>, G: Parser<I, O, E>, E: ParserError<I>,2494 pub fn length_and_then<I, O, N, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, O, E>
2495 where
2496 I: StreamIsPartial,
2497 I: Stream + UpdateSlice + Clone,
2498 N: ToUsize,
2499 F: Parser<I, N, E>,
2500 G: Parser<I, O, E>,
2501 E: ParserError<I>,
2502 {
2503 trace("length_and_then", move |i: &mut I| {
2504 let data = length_take(f.by_ref()).parse_next(i)?;
2505 let mut data = I::update_slice(i.clone(), data);
2506 let _ = data.complete();
2507 let o = g.by_ref().complete_err().parse_next(&mut data)?;
2508 Ok(o)
2509 })
2510 }
2511
2512 /// Deprecated since 0.5.27, replaced with [`length_and_then`]
2513 #[deprecated(since = "0.5.27", note = "Replaced with `length_and_then`")]
length_value<I, O, N, E, F, G>(f: F, g: G) -> impl Parser<I, O, E> where I: StreamIsPartial, I: Stream + UpdateSlice + Clone, N: ToUsize, F: Parser<I, N, E>, G: Parser<I, O, E>, E: ParserError<I>,2514 pub fn length_value<I, O, N, E, F, G>(f: F, g: G) -> impl Parser<I, O, E>
2515 where
2516 I: StreamIsPartial,
2517 I: Stream + UpdateSlice + Clone,
2518 N: ToUsize,
2519 F: Parser<I, N, E>,
2520 G: Parser<I, O, E>,
2521 E: ParserError<I>,
2522 {
2523 length_and_then(f, g)
2524 }
2525
2526 /// [`Accumulate`] a length-prefixed sequence of values ([TLV](https://en.wikipedia.org/wiki/Type-length-value))
2527 ///
2528 /// If the length represents token counts, see instead [`length_take`]
2529 ///
2530 /// # Arguments
2531 /// * `f` The parser to apply to obtain the count.
2532 /// * `g` The parser to apply repeatedly.
2533 ///
2534 /// # Example
2535 ///
2536 /// ```rust
2537 /// # #[cfg(feature = "std")] {
2538 /// # use winnow::prelude::*;
2539 /// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed};
2540 /// # use winnow::prelude::*;
2541 /// use winnow::Bytes;
2542 /// use winnow::binary::u8;
2543 /// use winnow::binary::length_count;
2544 /// use winnow::token::tag;
2545 ///
2546 /// type Stream<'i> = &'i Bytes;
2547 ///
2548 /// fn stream(b: &[u8]) -> Stream<'_> {
2549 /// Bytes::new(b)
2550 /// }
2551 ///
2552 /// fn parser(s: Stream<'_>) -> IResult<Stream<'_>, Vec<&[u8]>> {
2553 /// length_count(u8.map(|i| {
2554 /// println!("got number: {}", i);
2555 /// i
2556 /// }), "abc").parse_peek(s)
2557 /// }
2558 ///
2559 /// assert_eq!(parser(stream(b"\x02abcabcabc")), Ok((stream(b"abc"), vec![&b"abc"[..], &b"abc"[..]])));
2560 /// assert_eq!(parser(stream(b"\x03123123123")), Err(ErrMode::Backtrack(InputError::new(stream(b"123123123"), ErrorKind::Tag))));
2561 /// # }
2562 /// ```
length_repeat<I, O, C, N, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, C, E> where I: Stream, N: ToUsize, C: Accumulate<O>, F: Parser<I, N, E>, G: Parser<I, O, E>, E: ParserError<I>,2563 pub fn length_repeat<I, O, C, N, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, C, E>
2564 where
2565 I: Stream,
2566 N: ToUsize,
2567 C: Accumulate<O>,
2568 F: Parser<I, N, E>,
2569 G: Parser<I, O, E>,
2570 E: ParserError<I>,
2571 {
2572 trace("length_repeat", move |i: &mut I| {
2573 let n = f.parse_next(i)?;
2574 let n = n.to_usize();
2575 repeat(n, g.by_ref()).parse_next(i)
2576 })
2577 }
2578
2579 /// Deprecated since 0.5.27, replaced with [`length_repeat`]
2580 #[deprecated(since = "0.5.27", note = "Replaced with `length_repeat`")]
length_count<I, O, C, N, E, F, G>(f: F, g: G) -> impl Parser<I, C, E> where I: Stream, N: ToUsize, C: Accumulate<O>, F: Parser<I, N, E>, G: Parser<I, O, E>, E: ParserError<I>,2581 pub fn length_count<I, O, C, N, E, F, G>(f: F, g: G) -> impl Parser<I, C, E>
2582 where
2583 I: Stream,
2584 N: ToUsize,
2585 C: Accumulate<O>,
2586 F: Parser<I, N, E>,
2587 G: Parser<I, O, E>,
2588 E: ParserError<I>,
2589 {
2590 length_repeat(f, g)
2591 }
2592