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