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