Coverage Report

Created: 2026-02-14 06:16

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