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