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/// <div class="warning">
1214///
1215/// **Note:** that endianness does not apply to 1 byte numbers.
1216///
1217/// </div>
1218///
1219/// *Complete version*: returns an error if there is not enough input data
1220///
1221/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1222///
1223/// # Example
1224///
1225/// ```rust
1226/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1227/// # use winnow::prelude::*;
1228/// # use winnow::error::Needed::Size;
1229/// use winnow::binary::u8;
1230///
1231/// fn parser(s: &[u8]) -> IResult<&[u8], u8> {
1232///       u8.parse_peek(s)
1233/// }
1234///
1235/// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"\x03abcefg"[..], 0x00)));
1236/// assert_eq!(parser(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&[][..], ErrorKind::Token))));
1237/// ```
1238///
1239/// ```rust
1240/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1241/// # use winnow::prelude::*;
1242/// # use winnow::error::Needed::Size;
1243/// # use winnow::Partial;
1244/// use winnow::binary::u8;
1245///
1246/// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, u8> {
1247///       u8::<_, InputError<_>>.parse_peek(s)
1248/// }
1249///
1250/// assert_eq!(parser(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"\x03abcefg"[..]), 0x00)));
1251/// assert_eq!(parser(Partial::new(&b""[..])), Err(ErrMode::Incomplete(Needed::new(1))));
1252/// ```
1253#[inline(always)]
1254pub fn u8<Input, Error>(input: &mut Input) -> PResult<u8, Error>
1255where
1256    Input: StreamIsPartial + Stream<Token = u8>,
1257    Error: ParserError<Input>,
1258{
1259    trace("u8", move |input: &mut Input| {
1260        if <Input as StreamIsPartial>::is_partial_supported() {
1261            u8_::<_, _, true>(input)
1262        } else {
1263            u8_::<_, _, false>(input)
1264        }
1265    })
1266    .parse_next(input)
1267}
1268
1269fn u8_<Input, Error, const PARTIAL: bool>(input: &mut Input) -> PResult<u8, Error>
1270where
1271    Input: StreamIsPartial + Stream<Token = u8>,
1272    Error: ParserError<Input>,
1273{
1274    input.next_token().ok_or_else(|| {
1275        if PARTIAL && input.is_partial() {
1276            ErrMode::Incomplete(Needed::new(1))
1277        } else {
1278            ErrMode::Backtrack(Error::from_error_kind(input, ErrorKind::Token))
1279        }
1280    })
1281}
1282
1283/// Recognizes an unsigned 2 bytes integer
1284///
1285/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u16 integer,
1286/// otherwise if `winnow::binary::Endianness::Little` parse a little endian u16 integer.
1287///
1288/// *Complete version*: returns an error if there is not enough input data
1289///
1290/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1291///
1292/// # Example
1293///
1294/// ```rust
1295/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1296/// # use winnow::prelude::*;
1297/// # use winnow::error::Needed::Size;
1298/// use winnow::binary::u16;
1299///
1300/// let be_u16 = |s| {
1301///     u16(winnow::binary::Endianness::Big).parse_peek(s)
1302/// };
1303///
1304/// assert_eq!(be_u16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0003)));
1305/// assert_eq!(be_u16(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1306///
1307/// let le_u16 = |s| {
1308///     u16(winnow::binary::Endianness::Little).parse_peek(s)
1309/// };
1310///
1311/// assert_eq!(le_u16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0300)));
1312/// assert_eq!(le_u16(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1313/// ```
1314///
1315/// ```rust
1316/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1317/// # use winnow::prelude::*;
1318/// # use winnow::error::Needed::Size;
1319/// # use winnow::Partial;
1320/// use winnow::binary::u16;
1321///
1322/// let be_u16 = |s| {
1323///     u16::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1324/// };
1325///
1326/// assert_eq!(be_u16(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0003)));
1327/// assert_eq!(be_u16(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
1328///
1329/// let le_u16 = |s| {
1330///     u16::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1331/// };
1332///
1333/// assert_eq!(le_u16(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0300)));
1334/// assert_eq!(le_u16(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
1335/// ```
1336#[inline(always)]
1337pub fn u16<Input, Error>(endian: Endianness) -> impl Parser<Input, u16, Error>
1338where
1339    Input: StreamIsPartial + Stream<Token = u8>,
1340    Error: ParserError<Input>,
1341{
1342    move |input: &mut Input| {
1343        match endian {
1344            Endianness::Big => be_u16,
1345            Endianness::Little => le_u16,
1346            #[cfg(target_endian = "big")]
1347            Endianness::Native => be_u16,
1348            #[cfg(target_endian = "little")]
1349            Endianness::Native => le_u16,
1350        }
1351    }(input)
1352}
1353
1354/// Recognizes an unsigned 3 byte integer
1355///
1356/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u24 integer,
1357/// otherwise if `winnow::binary::Endianness::Little` parse a little endian u24 integer.
1358///
1359/// *Complete version*: returns an error if there is not enough input data
1360///
1361/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1362///
1363/// # Example
1364///
1365/// ```rust
1366/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1367/// # use winnow::prelude::*;
1368/// # use winnow::error::Needed::Size;
1369/// use winnow::binary::u24;
1370///
1371/// let be_u24 = |s| {
1372///     u24(winnow::binary::Endianness::Big).parse_peek(s)
1373/// };
1374///
1375/// assert_eq!(be_u24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x000305)));
1376/// assert_eq!(be_u24(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1377///
1378/// let le_u24 = |s| {
1379///     u24(winnow::binary::Endianness::Little).parse_peek(s)
1380/// };
1381///
1382/// assert_eq!(le_u24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x050300)));
1383/// assert_eq!(le_u24(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1384/// ```
1385///
1386/// ```rust
1387/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1388/// # use winnow::prelude::*;
1389/// # use winnow::error::Needed::Size;
1390/// # use winnow::Partial;
1391/// use winnow::binary::u24;
1392///
1393/// let be_u24 = |s| {
1394///     u24::<_,InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1395/// };
1396///
1397/// assert_eq!(be_u24(Partial::new(&b"\x00\x03\x05abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x000305)));
1398/// assert_eq!(be_u24(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2))));
1399///
1400/// let le_u24 = |s| {
1401///     u24::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1402/// };
1403///
1404/// assert_eq!(le_u24(Partial::new(&b"\x00\x03\x05abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x050300)));
1405/// assert_eq!(le_u24(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2))));
1406/// ```
1407#[inline(always)]
1408pub fn u24<Input, Error>(endian: Endianness) -> impl Parser<Input, u32, Error>
1409where
1410    Input: StreamIsPartial + Stream<Token = u8>,
1411    Error: ParserError<Input>,
1412{
1413    move |input: &mut Input| {
1414        match endian {
1415            Endianness::Big => be_u24,
1416            Endianness::Little => le_u24,
1417            #[cfg(target_endian = "big")]
1418            Endianness::Native => be_u24,
1419            #[cfg(target_endian = "little")]
1420            Endianness::Native => le_u24,
1421        }
1422    }(input)
1423}
1424
1425/// Recognizes an unsigned 4 byte integer
1426///
1427/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u32 integer,
1428/// otherwise if `winnow::binary::Endianness::Little` parse a little endian u32 integer.
1429///
1430/// *Complete version*: returns an error if there is not enough input data
1431///
1432/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1433///
1434/// # Example
1435///
1436/// ```rust
1437/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1438/// # use winnow::prelude::*;
1439/// # use winnow::error::Needed::Size;
1440/// use winnow::binary::u32;
1441///
1442/// let be_u32 = |s| {
1443///     u32(winnow::binary::Endianness::Big).parse_peek(s)
1444/// };
1445///
1446/// assert_eq!(be_u32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00030507)));
1447/// assert_eq!(be_u32(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1448///
1449/// let le_u32 = |s| {
1450///     u32(winnow::binary::Endianness::Little).parse_peek(s)
1451/// };
1452///
1453/// assert_eq!(le_u32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07050300)));
1454/// assert_eq!(le_u32(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1455/// ```
1456///
1457/// ```rust
1458/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1459/// # use winnow::prelude::*;
1460/// # use winnow::error::Needed::Size;
1461/// # use winnow::Partial;
1462/// use winnow::binary::u32;
1463///
1464/// let be_u32 = |s| {
1465///     u32::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1466/// };
1467///
1468/// assert_eq!(be_u32(Partial::new(&b"\x00\x03\x05\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x00030507)));
1469/// assert_eq!(be_u32(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3))));
1470///
1471/// let le_u32 = |s| {
1472///     u32::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1473/// };
1474///
1475/// assert_eq!(le_u32(Partial::new(&b"\x00\x03\x05\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x07050300)));
1476/// assert_eq!(le_u32(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3))));
1477/// ```
1478#[inline(always)]
1479pub fn u32<Input, Error>(endian: Endianness) -> impl Parser<Input, u32, Error>
1480where
1481    Input: StreamIsPartial + Stream<Token = u8>,
1482    Error: ParserError<Input>,
1483{
1484    move |input: &mut Input| {
1485        match endian {
1486            Endianness::Big => be_u32,
1487            Endianness::Little => le_u32,
1488            #[cfg(target_endian = "big")]
1489            Endianness::Native => be_u32,
1490            #[cfg(target_endian = "little")]
1491            Endianness::Native => le_u32,
1492        }
1493    }(input)
1494}
1495
1496/// Recognizes an unsigned 8 byte integer
1497///
1498/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u64 integer,
1499/// otherwise if `winnow::binary::Endianness::Little` parse a little endian u64 integer.
1500///
1501/// *Complete version*: returns an error if there is not enough input data
1502///
1503/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1504///
1505/// # Example
1506///
1507/// ```rust
1508/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1509/// # use winnow::prelude::*;
1510/// # use winnow::error::Needed::Size;
1511/// use winnow::binary::u64;
1512///
1513/// let be_u64 = |s| {
1514///     u64(winnow::binary::Endianness::Big).parse_peek(s)
1515/// };
1516///
1517/// assert_eq!(be_u64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0001020304050607)));
1518/// assert_eq!(be_u64(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1519///
1520/// let le_u64 = |s| {
1521///     u64(winnow::binary::Endianness::Little).parse_peek(s)
1522/// };
1523///
1524/// assert_eq!(le_u64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0706050403020100)));
1525/// assert_eq!(le_u64(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1526/// ```
1527///
1528/// ```rust
1529/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1530/// # use winnow::prelude::*;
1531/// # use winnow::error::Needed::Size;
1532/// # use winnow::Partial;
1533/// use winnow::binary::u64;
1534///
1535/// let be_u64 = |s| {
1536///     u64::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1537/// };
1538///
1539/// assert_eq!(be_u64(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0001020304050607)));
1540/// assert_eq!(be_u64(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7))));
1541///
1542/// let le_u64 = |s| {
1543///     u64::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1544/// };
1545///
1546/// assert_eq!(le_u64(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0706050403020100)));
1547/// assert_eq!(le_u64(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7))));
1548/// ```
1549#[inline(always)]
1550pub fn u64<Input, Error>(endian: Endianness) -> impl Parser<Input, u64, Error>
1551where
1552    Input: StreamIsPartial + Stream<Token = u8>,
1553    Error: ParserError<Input>,
1554{
1555    move |input: &mut Input| {
1556        match endian {
1557            Endianness::Big => be_u64,
1558            Endianness::Little => le_u64,
1559            #[cfg(target_endian = "big")]
1560            Endianness::Native => be_u64,
1561            #[cfg(target_endian = "little")]
1562            Endianness::Native => le_u64,
1563        }
1564    }(input)
1565}
1566
1567/// Recognizes an unsigned 16 byte integer
1568///
1569/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian u128 integer,
1570/// otherwise if `winnow::binary::Endianness::Little` parse a little endian u128 integer.
1571///
1572/// *Complete version*: returns an error if there is not enough input data
1573///
1574/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1575///
1576/// # Example
1577///
1578/// ```rust
1579/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1580/// # use winnow::prelude::*;
1581/// # use winnow::error::Needed::Size;
1582/// use winnow::binary::u128;
1583///
1584/// let be_u128 = |s| {
1585///     u128(winnow::binary::Endianness::Big).parse_peek(s)
1586/// };
1587///
1588/// 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)));
1589/// assert_eq!(be_u128(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1590///
1591/// let le_u128 = |s| {
1592///     u128(winnow::binary::Endianness::Little).parse_peek(s)
1593/// };
1594///
1595/// 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)));
1596/// assert_eq!(le_u128(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1597/// ```
1598///
1599/// ```rust
1600/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1601/// # use winnow::prelude::*;
1602/// # use winnow::error::Needed::Size;
1603/// # use winnow::Partial;
1604/// use winnow::binary::u128;
1605///
1606/// let be_u128 = |s| {
1607///     u128::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1608/// };
1609///
1610/// 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)));
1611/// assert_eq!(be_u128(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15))));
1612///
1613/// let le_u128 = |s| {
1614///     u128::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1615/// };
1616///
1617/// 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)));
1618/// assert_eq!(le_u128(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15))));
1619/// ```
1620#[inline(always)]
1621pub fn u128<Input, Error>(endian: Endianness) -> impl Parser<Input, u128, Error>
1622where
1623    Input: StreamIsPartial + Stream<Token = u8>,
1624    Error: ParserError<Input>,
1625{
1626    move |input: &mut Input| {
1627        match endian {
1628            Endianness::Big => be_u128,
1629            Endianness::Little => le_u128,
1630            #[cfg(target_endian = "big")]
1631            Endianness::Native => be_u128,
1632            #[cfg(target_endian = "little")]
1633            Endianness::Native => le_u128,
1634        }
1635    }(input)
1636}
1637
1638/// Recognizes a signed 1 byte integer
1639///
1640/// <div class="warning">
1641///
1642/// **Note:** that endianness does not apply to 1 byte numbers.
1643///
1644/// </div>
1645///
1646/// *Complete version*: returns an error if there is not enough input data
1647///
1648/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1649///
1650/// # Example
1651///
1652/// ```rust
1653/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1654/// # use winnow::prelude::*;
1655/// # use winnow::error::Needed::Size;
1656/// use winnow::binary::i8;
1657///
1658/// fn parser(s: &[u8]) -> IResult<&[u8], i8> {
1659///       i8.parse_peek(s)
1660/// }
1661///
1662/// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"\x03abcefg"[..], 0x00)));
1663/// assert_eq!(parser(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&[][..], ErrorKind::Token))));
1664/// ```
1665///
1666/// ```rust
1667/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1668/// # use winnow::prelude::*;
1669/// # use winnow::error::Needed::Size;
1670/// # use winnow::Partial;
1671/// use winnow::binary::i8;
1672///
1673/// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, i8> {
1674///       i8.parse_peek(s)
1675/// }
1676///
1677/// assert_eq!(parser(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"\x03abcefg"[..]), 0x00)));
1678/// assert_eq!(parser(Partial::new(&b""[..])), Err(ErrMode::Incomplete(Needed::new(1))));
1679/// ```
1680#[inline(always)]
1681pub fn i8<Input, Error>(input: &mut Input) -> PResult<i8, Error>
1682where
1683    Input: StreamIsPartial + Stream<Token = u8>,
1684    Error: ParserError<Input>,
1685{
1686    trace("i8", move |input: &mut Input| {
1687        if <Input as StreamIsPartial>::is_partial_supported() {
1688            u8_::<_, _, true>(input)
1689        } else {
1690            u8_::<_, _, false>(input)
1691        }
1692        .map(|n| n as i8)
1693    })
1694    .parse_next(input)
1695}
1696
1697/// Recognizes a signed 2 byte integer
1698///
1699/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i16 integer,
1700/// otherwise if `winnow::binary::Endianness::Little` parse a little endian i16 integer.
1701///
1702/// *Complete version*: returns an error if there is not enough input data
1703///
1704/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1705///
1706/// # Example
1707///
1708/// ```rust
1709/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1710/// # use winnow::prelude::*;
1711/// # use winnow::error::Needed::Size;
1712/// use winnow::binary::i16;
1713///
1714/// let be_i16 = |s| {
1715///     i16(winnow::binary::Endianness::Big).parse_peek(s)
1716/// };
1717///
1718/// assert_eq!(be_i16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0003)));
1719/// assert_eq!(be_i16(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1720///
1721/// let le_i16 = |s| {
1722///     i16(winnow::binary::Endianness::Little).parse_peek(s)
1723/// };
1724///
1725/// assert_eq!(le_i16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0300)));
1726/// assert_eq!(le_i16(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1727/// ```
1728///
1729/// ```rust
1730/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1731/// # use winnow::prelude::*;
1732/// # use winnow::error::Needed::Size;
1733/// # use winnow::Partial;
1734/// use winnow::binary::i16;
1735///
1736/// let be_i16 = |s| {
1737///     i16::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1738/// };
1739///
1740/// assert_eq!(be_i16(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0003)));
1741/// assert_eq!(be_i16(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
1742///
1743/// let le_i16 = |s| {
1744///     i16::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1745/// };
1746///
1747/// assert_eq!(le_i16(Partial::new(&b"\x00\x03abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0300)));
1748/// assert_eq!(le_i16(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
1749/// ```
1750#[inline(always)]
1751pub fn i16<Input, Error>(endian: Endianness) -> impl Parser<Input, i16, Error>
1752where
1753    Input: StreamIsPartial + Stream<Token = u8>,
1754    Error: ParserError<Input>,
1755{
1756    move |input: &mut Input| {
1757        match endian {
1758            Endianness::Big => be_i16,
1759            Endianness::Little => le_i16,
1760            #[cfg(target_endian = "big")]
1761            Endianness::Native => be_i16,
1762            #[cfg(target_endian = "little")]
1763            Endianness::Native => le_i16,
1764        }
1765    }(input)
1766}
1767
1768/// Recognizes a signed 3 byte integer
1769///
1770/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i24 integer,
1771/// otherwise if `winnow::binary::Endianness::Little` parse a little endian i24 integer.
1772///
1773/// *Complete version*: returns an error if there is not enough input data
1774///
1775/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1776///
1777/// # Example
1778///
1779/// ```rust
1780/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1781/// # use winnow::prelude::*;
1782/// # use winnow::error::Needed::Size;
1783/// use winnow::binary::i24;
1784///
1785/// let be_i24 = |s| {
1786///     i24(winnow::binary::Endianness::Big).parse_peek(s)
1787/// };
1788///
1789/// assert_eq!(be_i24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x000305)));
1790/// assert_eq!(be_i24(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1791///
1792/// let le_i24 = |s| {
1793///     i24(winnow::binary::Endianness::Little).parse_peek(s)
1794/// };
1795///
1796/// assert_eq!(le_i24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x050300)));
1797/// assert_eq!(le_i24(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1798/// ```
1799///
1800/// ```rust
1801/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1802/// # use winnow::prelude::*;
1803/// # use winnow::error::Needed::Size;
1804/// # use winnow::Partial;
1805/// use winnow::binary::i24;
1806///
1807/// let be_i24 = |s| {
1808///     i24::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1809/// };
1810///
1811/// assert_eq!(be_i24(Partial::new(&b"\x00\x03\x05abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x000305)));
1812/// assert_eq!(be_i24(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2))));
1813///
1814/// let le_i24 = |s| {
1815///     i24::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1816/// };
1817///
1818/// assert_eq!(le_i24(Partial::new(&b"\x00\x03\x05abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x050300)));
1819/// assert_eq!(le_i24(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(2))));
1820/// ```
1821#[inline(always)]
1822pub fn i24<Input, Error>(endian: Endianness) -> impl Parser<Input, i32, Error>
1823where
1824    Input: StreamIsPartial + Stream<Token = u8>,
1825    Error: ParserError<Input>,
1826{
1827    move |input: &mut Input| {
1828        match endian {
1829            Endianness::Big => be_i24,
1830            Endianness::Little => le_i24,
1831            #[cfg(target_endian = "big")]
1832            Endianness::Native => be_i24,
1833            #[cfg(target_endian = "little")]
1834            Endianness::Native => le_i24,
1835        }
1836    }(input)
1837}
1838
1839/// Recognizes a signed 4 byte integer
1840///
1841/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i32 integer,
1842/// otherwise if `winnow::binary::Endianness::Little` parse a little endian i32 integer.
1843///
1844/// *Complete version*: returns an error if there is not enough input data
1845///
1846/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1847///
1848/// # Example
1849///
1850/// ```rust
1851/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1852/// # use winnow::prelude::*;
1853/// # use winnow::error::Needed::Size;
1854/// use winnow::binary::i32;
1855///
1856/// let be_i32 = |s| {
1857///     i32(winnow::binary::Endianness::Big).parse_peek(s)
1858/// };
1859///
1860/// assert_eq!(be_i32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00030507)));
1861/// assert_eq!(be_i32(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1862///
1863/// let le_i32 = |s| {
1864///     i32(winnow::binary::Endianness::Little).parse_peek(s)
1865/// };
1866///
1867/// assert_eq!(le_i32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07050300)));
1868/// assert_eq!(le_i32(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1869/// ```
1870///
1871/// ```rust
1872/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1873/// # use winnow::prelude::*;
1874/// # use winnow::error::Needed::Size;
1875/// # use winnow::Partial;
1876/// use winnow::binary::i32;
1877///
1878/// let be_i32 = |s| {
1879///     i32::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1880/// };
1881///
1882/// assert_eq!(be_i32(Partial::new(&b"\x00\x03\x05\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x00030507)));
1883/// assert_eq!(be_i32(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3))));
1884///
1885/// let le_i32 = |s| {
1886///     i32::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1887/// };
1888///
1889/// assert_eq!(le_i32(Partial::new(&b"\x00\x03\x05\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x07050300)));
1890/// assert_eq!(le_i32(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(3))));
1891/// ```
1892#[inline(always)]
1893pub fn i32<Input, Error>(endian: Endianness) -> impl Parser<Input, i32, Error>
1894where
1895    Input: StreamIsPartial + Stream<Token = u8>,
1896    Error: ParserError<Input>,
1897{
1898    move |input: &mut Input| {
1899        match endian {
1900            Endianness::Big => be_i32,
1901            Endianness::Little => le_i32,
1902            #[cfg(target_endian = "big")]
1903            Endianness::Native => be_i32,
1904            #[cfg(target_endian = "little")]
1905            Endianness::Native => le_i32,
1906        }
1907    }(input)
1908}
1909
1910/// Recognizes a signed 8 byte integer
1911///
1912/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i64 integer,
1913/// otherwise if `winnow::binary::Endianness::Little` parse a little endian i64 integer.
1914///
1915/// *Complete version*: returns an error if there is not enough input data
1916///
1917/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1918///
1919/// # Example
1920///
1921/// ```rust
1922/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1923/// # use winnow::prelude::*;
1924/// # use winnow::error::Needed::Size;
1925/// use winnow::binary::i64;
1926///
1927/// let be_i64 = |s| {
1928///     i64(winnow::binary::Endianness::Big).parse_peek(s)
1929/// };
1930///
1931/// assert_eq!(be_i64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0001020304050607)));
1932/// assert_eq!(be_i64(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1933///
1934/// let le_i64 = |s| {
1935///     i64(winnow::binary::Endianness::Little).parse_peek(s)
1936/// };
1937///
1938/// assert_eq!(le_i64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0706050403020100)));
1939/// assert_eq!(le_i64(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
1940/// ```
1941///
1942/// ```rust
1943/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1944/// # use winnow::prelude::*;
1945/// # use winnow::error::Needed::Size;
1946/// # use winnow::Partial;
1947/// use winnow::binary::i64;
1948///
1949/// let be_i64 = |s| {
1950///     i64::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
1951/// };
1952///
1953/// assert_eq!(be_i64(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0001020304050607)));
1954/// assert_eq!(be_i64(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7))));
1955///
1956/// let le_i64 = |s| {
1957///     i64::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
1958/// };
1959///
1960/// assert_eq!(le_i64(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x0706050403020100)));
1961/// assert_eq!(le_i64(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(7))));
1962/// ```
1963#[inline(always)]
1964pub fn i64<Input, Error>(endian: Endianness) -> impl Parser<Input, i64, Error>
1965where
1966    Input: StreamIsPartial + Stream<Token = u8>,
1967    Error: ParserError<Input>,
1968{
1969    move |input: &mut Input| {
1970        match endian {
1971            Endianness::Big => be_i64,
1972            Endianness::Little => le_i64,
1973            #[cfg(target_endian = "big")]
1974            Endianness::Native => be_i64,
1975            #[cfg(target_endian = "little")]
1976            Endianness::Native => le_i64,
1977        }
1978    }(input)
1979}
1980
1981/// Recognizes a signed 16 byte integer
1982///
1983/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian i128 integer,
1984/// otherwise if `winnow::binary::Endianness::Little` parse a little endian i128 integer.
1985///
1986/// *Complete version*: returns an error if there is not enough input data
1987///
1988/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
1989///
1990/// # Example
1991///
1992/// ```rust
1993/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
1994/// # use winnow::prelude::*;
1995/// # use winnow::error::Needed::Size;
1996/// use winnow::binary::i128;
1997///
1998/// let be_i128 = |s| {
1999///     i128(winnow::binary::Endianness::Big).parse_peek(s)
2000/// };
2001///
2002/// assert_eq!(be_i128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00010203040506070001020304050607)));
2003/// assert_eq!(be_i128(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
2004///
2005/// let le_i128 = |s| {
2006///     i128(winnow::binary::Endianness::Little).parse_peek(s)
2007/// };
2008///
2009/// assert_eq!(le_i128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07060504030201000706050403020100)));
2010/// assert_eq!(le_i128(&b"\x01"[..]), Err(ErrMode::Backtrack(InputError::new(&[0x01][..], ErrorKind::Slice))));
2011/// ```
2012///
2013/// ```rust
2014/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2015/// # use winnow::prelude::*;
2016/// # use winnow::error::Needed::Size;
2017/// # use winnow::Partial;
2018/// use winnow::binary::i128;
2019///
2020/// let be_i128 = |s| {
2021///     i128::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
2022/// };
2023///
2024/// assert_eq!(be_i128(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x00010203040506070001020304050607)));
2025/// assert_eq!(be_i128(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15))));
2026///
2027/// let le_i128 = |s| {
2028///     i128::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
2029/// };
2030///
2031/// assert_eq!(le_i128(Partial::new(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..])), Ok((Partial::new(&b"abcefg"[..]), 0x07060504030201000706050403020100)));
2032/// assert_eq!(le_i128(Partial::new(&b"\x01"[..])), Err(ErrMode::Incomplete(Needed::new(15))));
2033/// ```
2034#[inline(always)]
2035pub fn i128<Input, Error>(endian: Endianness) -> impl Parser<Input, i128, Error>
2036where
2037    Input: StreamIsPartial + Stream<Token = u8>,
2038    Error: ParserError<Input>,
2039{
2040    move |input: &mut Input| {
2041        match endian {
2042            Endianness::Big => be_i128,
2043            Endianness::Little => le_i128,
2044            #[cfg(target_endian = "big")]
2045            Endianness::Native => be_i128,
2046            #[cfg(target_endian = "little")]
2047            Endianness::Native => le_i128,
2048        }
2049    }(input)
2050}
2051
2052/// Recognizes a big endian 4 bytes floating point number.
2053///
2054/// *Complete version*: Returns an error if there is not enough input data.
2055///
2056/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2057///
2058/// # Example
2059///
2060/// ```rust
2061/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2062/// # use winnow::prelude::*;
2063/// # use winnow::prelude::*;
2064/// # use winnow::error::Needed::Size;
2065/// use winnow::binary::be_f32;
2066///
2067/// fn parser(s: &[u8]) -> IResult<&[u8], f32> {
2068///       be_f32.parse_peek(s)
2069/// }
2070///
2071/// assert_eq!(parser(&[0x41, 0x48, 0x00, 0x00][..]), Ok((&b""[..], 12.5)));
2072/// assert_eq!(parser(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2073/// ```
2074///
2075/// ```rust
2076/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2077/// # use winnow::prelude::*;
2078/// # use winnow::Partial;
2079/// use winnow::binary::be_f32;
2080///
2081/// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, f32> {
2082///       be_f32.parse_peek(s)
2083/// }
2084///
2085/// assert_eq!(parser(Partial::new(&[0x40, 0x29, 0x00, 0x00][..])), Ok((Partial::new(&b""[..]), 2.640625)));
2086/// assert_eq!(parser(Partial::new(&[0x01][..])), Err(ErrMode::Incomplete(Needed::new(3))));
2087/// ```
2088#[inline(always)]
2089pub fn be_f32<Input, Error>(input: &mut Input) -> PResult<f32, Error>
2090where
2091    Input: StreamIsPartial + Stream<Token = u8>,
2092    Error: ParserError<Input>,
2093{
2094    trace("be_f32", move |input: &mut Input| {
2095        be_uint::<_, u32, _>(input, 4).map(f32::from_bits)
2096    })
2097    .parse_next(input)
2098}
2099
2100/// Recognizes a big endian 8 bytes floating point number.
2101///
2102/// *Complete version*: Returns an error if there is not enough input data.
2103///
2104/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2105///
2106/// # Example
2107///
2108/// ```rust
2109/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2110/// # use winnow::prelude::*;
2111/// # use winnow::error::Needed::Size;
2112/// use winnow::binary::be_f64;
2113///
2114/// fn parser(s: &[u8]) -> IResult<&[u8], f64> {
2115///       be_f64.parse_peek(s)
2116/// }
2117///
2118/// assert_eq!(parser(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 12.5)));
2119/// assert_eq!(parser(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2120/// ```
2121///
2122/// ```rust
2123/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2124/// # use winnow::prelude::*;
2125/// # use winnow::Partial;
2126/// use winnow::binary::be_f64;
2127///
2128/// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, f64> {
2129///       be_f64::<_, InputError<_>>.parse_peek(s)
2130/// }
2131///
2132/// assert_eq!(parser(Partial::new(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..])), Ok((Partial::new(&b""[..]), 12.5)));
2133/// assert_eq!(parser(Partial::new(&[0x01][..])), Err(ErrMode::Incomplete(Needed::new(7))));
2134/// ```
2135#[inline(always)]
2136pub fn be_f64<Input, Error>(input: &mut Input) -> PResult<f64, Error>
2137where
2138    Input: StreamIsPartial + Stream<Token = u8>,
2139    Error: ParserError<Input>,
2140{
2141    trace("be_f64", move |input: &mut Input| {
2142        be_uint::<_, u64, _>(input, 8).map(f64::from_bits)
2143    })
2144    .parse_next(input)
2145}
2146
2147/// Recognizes a little endian 4 bytes floating point number.
2148///
2149/// *Complete version*: Returns an error if there is not enough input data.
2150///
2151/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2152///
2153/// # Example
2154///
2155/// ```rust
2156/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2157/// # use winnow::prelude::*;
2158/// # use winnow::error::Needed::Size;
2159/// use winnow::binary::le_f32;
2160///
2161/// fn parser(s: &[u8]) -> IResult<&[u8], f32> {
2162///       le_f32.parse_peek(s)
2163/// }
2164///
2165/// assert_eq!(parser(&[0x00, 0x00, 0x48, 0x41][..]), Ok((&b""[..], 12.5)));
2166/// assert_eq!(parser(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2167/// ```
2168///
2169/// ```rust
2170/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2171/// # use winnow::prelude::*;
2172/// # use winnow::Partial;
2173/// use winnow::binary::le_f32;
2174///
2175/// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, f32> {
2176///       le_f32::<_, InputError<_>>.parse_peek(s)
2177/// }
2178///
2179/// assert_eq!(parser(Partial::new(&[0x00, 0x00, 0x48, 0x41][..])), Ok((Partial::new(&b""[..]), 12.5)));
2180/// assert_eq!(parser(Partial::new(&[0x01][..])), Err(ErrMode::Incomplete(Needed::new(3))));
2181/// ```
2182#[inline(always)]
2183pub fn le_f32<Input, Error>(input: &mut Input) -> PResult<f32, Error>
2184where
2185    Input: StreamIsPartial + Stream<Token = u8>,
2186    Error: ParserError<Input>,
2187{
2188    trace("le_f32", move |input: &mut Input| {
2189        le_uint::<_, u32, _>(input, 4).map(f32::from_bits)
2190    })
2191    .parse_next(input)
2192}
2193
2194/// Recognizes a little endian 8 bytes floating point number.
2195///
2196/// *Complete version*: Returns an error if there is not enough input data.
2197///
2198/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2199///
2200/// # Example
2201///
2202/// ```rust
2203/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2204/// # use winnow::prelude::*;
2205/// # use winnow::error::Needed::Size;
2206/// use winnow::binary::le_f64;
2207///
2208/// fn parser(s: &[u8]) -> IResult<&[u8], f64> {
2209///       le_f64.parse_peek(s)
2210/// }
2211///
2212/// assert_eq!(parser(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40][..]), Ok((&b""[..], 12.5)));
2213/// assert_eq!(parser(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2214/// ```
2215///
2216/// ```rust
2217/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2218/// # use winnow::prelude::*;
2219/// # use winnow::Partial;
2220/// use winnow::binary::le_f64;
2221///
2222/// fn parser(s: Partial<&[u8]>) -> IResult<Partial<&[u8]>, f64> {
2223///       le_f64::<_, InputError<_>>.parse_peek(s)
2224/// }
2225///
2226/// assert_eq!(parser(Partial::new(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41][..])), Ok((Partial::new(&b""[..]), 3145728.0)));
2227/// assert_eq!(parser(Partial::new(&[0x01][..])), Err(ErrMode::Incomplete(Needed::new(7))));
2228/// ```
2229#[inline(always)]
2230pub fn le_f64<Input, Error>(input: &mut Input) -> PResult<f64, Error>
2231where
2232    Input: StreamIsPartial + Stream<Token = u8>,
2233    Error: ParserError<Input>,
2234{
2235    trace("be_f64", move |input: &mut Input| {
2236        le_uint::<_, u64, _>(input, 8).map(f64::from_bits)
2237    })
2238    .parse_next(input)
2239}
2240
2241/// Recognizes a 4 byte floating point number
2242///
2243/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian f32 float,
2244/// otherwise if `winnow::binary::Endianness::Little` parse a little endian f32 float.
2245///
2246/// *Complete version*: returns an error if there is not enough input data
2247///
2248/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2249///
2250/// # Example
2251///
2252/// ```rust
2253/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2254/// # use winnow::prelude::*;
2255/// # use winnow::error::Needed::Size;
2256/// use winnow::binary::f32;
2257///
2258/// let be_f32 = |s| {
2259///     f32(winnow::binary::Endianness::Big).parse_peek(s)
2260/// };
2261///
2262/// assert_eq!(be_f32(&[0x41, 0x48, 0x00, 0x00][..]), Ok((&b""[..], 12.5)));
2263/// assert_eq!(be_f32(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2264///
2265/// let le_f32 = |s| {
2266///     f32(winnow::binary::Endianness::Little).parse_peek(s)
2267/// };
2268///
2269/// assert_eq!(le_f32(&[0x00, 0x00, 0x48, 0x41][..]), Ok((&b""[..], 12.5)));
2270/// assert_eq!(le_f32(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2271/// ```
2272///
2273/// ```rust
2274/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2275/// # use winnow::prelude::*;
2276/// # use winnow::error::Needed::Size;
2277/// # use winnow::Partial;
2278/// use winnow::binary::f32;
2279///
2280/// let be_f32 = |s| {
2281///     f32::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
2282/// };
2283///
2284/// assert_eq!(be_f32(Partial::new(&[0x41, 0x48, 0x00, 0x00][..])), Ok((Partial::new(&b""[..]), 12.5)));
2285/// assert_eq!(be_f32(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
2286///
2287/// let le_f32 = |s| {
2288///     f32::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
2289/// };
2290///
2291/// assert_eq!(le_f32(Partial::new(&[0x00, 0x00, 0x48, 0x41][..])), Ok((Partial::new(&b""[..]), 12.5)));
2292/// assert_eq!(le_f32(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
2293/// ```
2294#[inline(always)]
2295pub fn f32<Input, Error>(endian: Endianness) -> impl Parser<Input, f32, Error>
2296where
2297    Input: StreamIsPartial + Stream<Token = u8>,
2298    Error: ParserError<Input>,
2299{
2300    move |input: &mut Input| {
2301        match endian {
2302            Endianness::Big => be_f32,
2303            Endianness::Little => le_f32,
2304            #[cfg(target_endian = "big")]
2305            Endianness::Native => be_f32,
2306            #[cfg(target_endian = "little")]
2307            Endianness::Native => le_f32,
2308        }
2309    }(input)
2310}
2311
2312/// Recognizes an 8 byte floating point number
2313///
2314/// If the parameter is `winnow::binary::Endianness::Big`, parse a big endian f64 float,
2315/// otherwise if `winnow::binary::Endianness::Little` parse a little endian f64 float.
2316///
2317/// *Complete version*: returns an error if there is not enough input data
2318///
2319/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2320///
2321/// # Example
2322///
2323/// ```rust
2324/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2325/// # use winnow::prelude::*;
2326/// # use winnow::error::Needed::Size;
2327/// use winnow::binary::f64;
2328///
2329/// let be_f64 = |s| {
2330///     f64(winnow::binary::Endianness::Big).parse_peek(s)
2331/// };
2332///
2333/// assert_eq!(be_f64(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 12.5)));
2334/// assert_eq!(be_f64(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2335///
2336/// let le_f64 = |s| {
2337///     f64(winnow::binary::Endianness::Little).parse_peek(s)
2338/// };
2339///
2340/// assert_eq!(le_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40][..]), Ok((&b""[..], 12.5)));
2341/// assert_eq!(le_f64(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
2342/// ```
2343///
2344/// ```rust
2345/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, error::Needed};
2346/// # use winnow::prelude::*;
2347/// # use winnow::error::Needed::Size;
2348/// # use winnow::Partial;
2349/// use winnow::binary::f64;
2350///
2351/// let be_f64 = |s| {
2352///     f64::<_, InputError<_>>(winnow::binary::Endianness::Big).parse_peek(s)
2353/// };
2354///
2355/// assert_eq!(be_f64(Partial::new(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..])), Ok((Partial::new(&b""[..]), 12.5)));
2356/// assert_eq!(be_f64(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(5))));
2357///
2358/// let le_f64 = |s| {
2359///     f64::<_, InputError<_>>(winnow::binary::Endianness::Little).parse_peek(s)
2360/// };
2361///
2362/// assert_eq!(le_f64(Partial::new(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40][..])), Ok((Partial::new(&b""[..]), 12.5)));
2363/// assert_eq!(le_f64(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(5))));
2364/// ```
2365#[inline(always)]
2366pub fn f64<Input, Error>(endian: Endianness) -> impl Parser<Input, f64, Error>
2367where
2368    Input: StreamIsPartial + Stream<Token = u8>,
2369    Error: ParserError<Input>,
2370{
2371    move |input: &mut Input| {
2372        match endian {
2373            Endianness::Big => be_f64,
2374            Endianness::Little => le_f64,
2375            #[cfg(target_endian = "big")]
2376            Endianness::Native => be_f64,
2377            #[cfg(target_endian = "little")]
2378            Endianness::Native => le_f64,
2379        }
2380    }(input)
2381}
2382
2383/// Get a length-prefixed slice ([TLV](https://en.wikipedia.org/wiki/Type-length-value))
2384///
2385/// To apply a parser to the returned slice, see [`length_and_then`].
2386///
2387/// If the count is for something besides tokens, see [`length_repeat`].
2388///
2389/// *Complete version*: Returns an error if there is not enough input data.
2390///
2391/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2392///
2393/// # Example
2394///
2395/// ```rust
2396/// # use winnow::{error::ErrMode, error::ErrorKind, error::Needed, stream::Partial};
2397/// # use winnow::prelude::*;
2398/// use winnow::Bytes;
2399/// use winnow::binary::be_u16;
2400/// use winnow::binary::length_take;
2401///
2402/// type Stream<'i> = Partial<&'i Bytes>;
2403///
2404/// fn stream(b: &[u8]) -> Stream<'_> {
2405///     Partial::new(Bytes::new(b))
2406/// }
2407///
2408/// fn parser(s: Stream<'_>) -> IResult<Stream<'_>, &[u8]> {
2409///   length_take(be_u16).parse_peek(s)
2410/// }
2411///
2412/// assert_eq!(parser(stream(b"\x00\x03abcefg")), Ok((stream(&b"efg"[..]), &b"abc"[..])));
2413/// assert_eq!(parser(stream(b"\x00\x03a")), Err(ErrMode::Incomplete(Needed::new(2))));
2414/// ```
2415pub fn length_take<Input, Count, Error, CountParser>(
2416    mut count: CountParser,
2417) -> impl Parser<Input, <Input as Stream>::Slice, Error>
2418where
2419    Input: StreamIsPartial + Stream,
2420    Count: ToUsize,
2421    CountParser: Parser<Input, Count, Error>,
2422    Error: ParserError<Input>,
2423{
2424    trace("length_take", move |i: &mut Input| {
2425        let length = count.parse_next(i)?;
2426
2427        crate::token::take(length).parse_next(i)
2428    })
2429}
2430
2431/// Parse a length-prefixed slice ([TLV](https://en.wikipedia.org/wiki/Type-length-value))
2432///
2433/// *Complete version*: Returns an error if there is not enough input data.
2434///
2435/// *[Partial version][crate::_topic::partial]*: Will return `Err(winnow::error::ErrMode::Incomplete(_))` if there is not enough data.
2436///
2437/// # Example
2438///
2439/// ```rust
2440/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed, stream::{Partial, StreamIsPartial}};
2441/// # use winnow::prelude::*;
2442/// use winnow::Bytes;
2443/// use winnow::binary::be_u16;
2444/// use winnow::binary::length_and_then;
2445///
2446/// type Stream<'i> = Partial<&'i Bytes>;
2447///
2448/// fn stream(b: &[u8]) -> Stream<'_> {
2449///     Partial::new(Bytes::new(b))
2450/// }
2451///
2452/// fn complete_stream(b: &[u8]) -> Stream<'_> {
2453///     let mut p = Partial::new(Bytes::new(b));
2454///     let _ = p.complete();
2455///     p
2456/// }
2457///
2458/// fn parser(s: Stream<'_>) -> IResult<Stream<'_>, &[u8]> {
2459///   length_and_then(be_u16, "abc").parse_peek(s)
2460/// }
2461///
2462/// assert_eq!(parser(stream(b"\x00\x03abcefg")), Ok((stream(&b"efg"[..]), &b"abc"[..])));
2463/// assert_eq!(parser(stream(b"\x00\x03123123")), Err(ErrMode::Backtrack(InputError::new(complete_stream(&b"123"[..]), ErrorKind::Tag))));
2464/// assert_eq!(parser(stream(b"\x00\x03a")), Err(ErrMode::Incomplete(Needed::new(2))));
2465/// ```
2466pub fn length_and_then<Input, Output, Count, Error, CountParser, ParseNext>(
2467    mut count: CountParser,
2468    mut parser: ParseNext,
2469) -> impl Parser<Input, Output, Error>
2470where
2471    Input: StreamIsPartial + Stream + UpdateSlice + Clone,
2472    Count: ToUsize,
2473    CountParser: Parser<Input, Count, Error>,
2474    ParseNext: Parser<Input, Output, Error>,
2475    Error: ParserError<Input>,
2476{
2477    trace("length_and_then", move |i: &mut Input| {
2478        let data = length_take(count.by_ref()).parse_next(i)?;
2479        let mut data = Input::update_slice(i.clone(), data);
2480        let _ = data.complete();
2481        let o = parser.by_ref().complete_err().parse_next(&mut data)?;
2482        Ok(o)
2483    })
2484}
2485
2486/// [`Accumulate`] a length-prefixed sequence of values ([TLV](https://en.wikipedia.org/wiki/Type-length-value))
2487///
2488/// If the length represents token counts, see instead [`length_take`]
2489///
2490/// # Example
2491///
2492/// ```rust
2493/// # #[cfg(feature = "std")] {
2494/// # use winnow::prelude::*;
2495/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed};
2496/// # use winnow::prelude::*;
2497/// use winnow::Bytes;
2498/// use winnow::binary::u8;
2499/// use winnow::binary::length_repeat;
2500///
2501/// type Stream<'i> = &'i Bytes;
2502///
2503/// fn stream(b: &[u8]) -> Stream<'_> {
2504///     Bytes::new(b)
2505/// }
2506///
2507/// fn parser(s: Stream<'_>) -> IResult<Stream<'_>, Vec<&[u8]>> {
2508///   length_repeat(u8.map(|i| {
2509///      println!("got number: {}", i);
2510///      i
2511///   }), "abc").parse_peek(s)
2512/// }
2513///
2514/// assert_eq!(parser(stream(b"\x02abcabcabc")), Ok((stream(b"abc"), vec![&b"abc"[..], &b"abc"[..]])));
2515/// assert_eq!(parser(stream(b"\x03123123123")), Err(ErrMode::Backtrack(InputError::new(stream(b"123123123"), ErrorKind::Tag))));
2516/// # }
2517/// ```
2518pub fn length_repeat<Input, Output, Accumulator, Count, Error, CountParser, ParseNext>(
2519    mut count: CountParser,
2520    mut parser: ParseNext,
2521) -> impl Parser<Input, Accumulator, Error>
2522where
2523    Input: Stream,
2524    Count: ToUsize,
2525    Accumulator: Accumulate<Output>,
2526    CountParser: Parser<Input, Count, Error>,
2527    ParseNext: Parser<Input, Output, Error>,
2528    Error: ParserError<Input>,
2529{
2530    trace("length_repeat", move |i: &mut Input| {
2531        let n = count.parse_next(i)?;
2532        let n = n.to_usize();
2533        repeat(n, parser.by_ref()).parse_next(i)
2534    })
2535}