winnow/binary/
mod.rs

1//! Parsers recognizing numbers
2
3#![allow(clippy::match_same_arms)]
4
5pub mod bits;
6
7#[cfg(test)]
8mod tests;
9
10use crate::combinator::repeat;
11use crate::combinator::trace;
12use crate::error::ErrMode;
13use crate::error::ErrorKind;
14use crate::error::Needed;
15use crate::error::ParserError;
16use crate::lib::std::ops::{Add, Shl};
17use crate::stream::Accumulate;
18use crate::stream::{AsBytes, Stream, StreamIsPartial};
19use crate::stream::{ToUsize, UpdateSlice};
20use crate::token::take;
21use crate::PResult;
22use crate::Parser;
23
24/// Configurable endianness
25#[derive(Debug, PartialEq, Eq, Clone, Copy)]
26pub 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)]
71pub fn be_u8<I, E: ParserError<I>>(input: &mut I) -> PResult<u8, E>
72where
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)]
115pub fn be_u16<I, E: ParserError<I>>(input: &mut I) -> PResult<u16, E>
116where
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)]
160pub fn be_u24<I, E: ParserError<I>>(input: &mut I) -> PResult<u32, E>
161where
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)]
205pub fn be_u32<I, E: ParserError<I>>(input: &mut I) -> PResult<u32, E>
206where
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)]
250pub fn be_u64<I, E: ParserError<I>>(input: &mut I) -> PResult<u64, E>
251where
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)]
295pub fn be_u128<I, E: ParserError<I>>(input: &mut I) -> PResult<u128, E>
296where
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]
305fn be_uint<I, Uint, E: ParserError<I>>(input: &mut I, bound: usize) -> PResult<Uint, E>
306where
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]
319fn to_be_uint<Uint>(number: &[u8]) -> Uint
320where
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)]
367pub fn be_i8<I, E: ParserError<I>>(input: &mut I) -> PResult<i8, E>
368where
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)]
411pub fn be_i16<I, E: ParserError<I>>(input: &mut I) -> PResult<i16, E>
412where
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)]
459pub fn be_i24<I, E: ParserError<I>>(input: &mut I) -> PResult<i32, E>
460where
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)]
515pub fn be_i32<I, E: ParserError<I>>(input: &mut I) -> PResult<i32, E>
516where
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)]
563pub fn be_i64<I, E: ParserError<I>>(input: &mut I) -> PResult<i64, E>
564where
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)]
611pub fn be_i128<I, E: ParserError<I>>(input: &mut I) -> PResult<i128, E>
612where
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)]
659pub fn le_u8<I, E: ParserError<I>>(input: &mut I) -> PResult<u8, E>
660where
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)]
703pub fn le_u16<I, E: ParserError<I>>(input: &mut I) -> PResult<u16, E>
704where
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)]
748pub fn le_u24<I, E: ParserError<I>>(input: &mut I) -> PResult<u32, E>
749where
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)]
793pub fn le_u32<I, E: ParserError<I>>(input: &mut I) -> PResult<u32, E>
794where
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)]
838pub fn le_u64<I, E: ParserError<I>>(input: &mut I) -> PResult<u64, E>
839where
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)]
883pub fn le_u128<I, E: ParserError<I>>(input: &mut I) -> PResult<u128, E>
884where
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]
893fn le_uint<I, Uint, E: ParserError<I>>(input: &mut I, bound: usize) -> PResult<Uint, E>
894where
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]
906fn to_le_uint<Uint>(number: &[u8]) -> Uint
907where
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)]
954pub fn le_i8<I, E: ParserError<I>>(input: &mut I) -> PResult<i8, E>
955where
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)]
998pub fn le_i16<I, E: ParserError<I>>(input: &mut I) -> PResult<i16, E>
999where
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)]
1046pub fn le_i24<I, E: ParserError<I>>(input: &mut I) -> PResult<i32, E>
1047where
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)]
1102pub fn le_i32<I, E: ParserError<I>>(input: &mut I) -> PResult<i32, E>
1103where
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)]
1150pub fn le_i64<I, E: ParserError<I>>(input: &mut I) -> PResult<i64, E>
1151where
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)]
1198pub fn le_i128<I, E: ParserError<I>>(input: &mut I) -> PResult<i128, E>
1199where
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)]
1249pub fn u8<I, E: ParserError<I>>(input: &mut I) -> PResult<u8, E>
1250where
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
1264fn u8_<I, E: ParserError<I>, const PARTIAL: bool>(input: &mut I) -> PResult<u8, E>
1265where
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)]
1332pub fn u16<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u16, E>
1333where
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)]
1404pub fn u24<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u32, E>
1405where
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)]
1476pub fn u32<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u32, E>
1477where
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)]
1548pub fn u64<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u64, E>
1549where
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)]
1620pub fn u128<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, u128, E>
1621where
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)]
1677pub fn i8<I, E: ParserError<I>>(input: &mut I) -> PResult<i8, E>
1678where
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)]
1747pub fn i16<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i16, E>
1748where
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)]
1819pub fn i24<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i32, E>
1820where
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)]
1891pub fn i32<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i32, E>
1892where
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)]
1963pub fn i64<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i64, E>
1964where
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)]
2035pub fn i128<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, i128, E>
2036where
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)]
2090pub fn be_f32<I, E: ParserError<I>>(input: &mut I) -> PResult<f32, E>
2091where
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)]
2138pub fn be_f64<I, E: ParserError<I>>(input: &mut I) -> PResult<f64, E>
2139where
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)]
2186pub fn le_f32<I, E: ParserError<I>>(input: &mut I) -> PResult<f32, E>
2187where
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)]
2234pub fn le_f64<I, E: ParserError<I>>(input: &mut I) -> PResult<f64, E>
2235where
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)]
2300pub fn f32<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, f32, E>
2301where
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)]
2372pub fn f64<I, E: ParserError<I>>(endian: Endianness) -> impl Parser<I, f64, E>
2373where
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/// ```
2426pub fn length_take<I, N, E, F>(mut f: F) -> impl Parser<I, <I as Stream>::Slice, E>
2427where
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`")]
2443pub fn length_data<I, N, E, F>(f: F) -> impl Parser<I, <I as Stream>::Slice, E>
2444where
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/// ```
2494pub fn length_and_then<I, O, N, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, O, E>
2495where
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`")]
2514pub fn length_value<I, O, N, E, F, G>(f: F, g: G) -> impl Parser<I, O, E>
2515where
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/// ```
2563pub fn length_repeat<I, O, C, N, E, F, G>(mut f: F, mut g: G) -> impl Parser<I, C, E>
2564where
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`")]
2581pub fn length_count<I, O, C, N, E, F, G>(f: F, g: G) -> impl Parser<I, C, E>
2582where
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}