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