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