Coverage Report

Created: 2026-01-09 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/combine-4.6.7/src/parser/byte.rs
Line
Count
Source
1
//! Module containing parsers specialized on byte streams.
2
3
use crate::{
4
    error::{self, ParseResult::*},
5
    parser::{
6
        combinator::no_partial,
7
        range::{take_fn, TakeRange},
8
        repeat::skip_many,
9
        token::{satisfy, token, tokens_cmp, Token},
10
    },
11
    stream::{RangeStream, Stream},
12
    Parser,
13
};
14
15
/// Parses a byte and succeeds if the byte is equal to `c`.
16
///
17
/// ```
18
/// use combine::Parser;
19
/// use combine::parser::byte::byte;
20
/// assert_eq!(byte(b'!').parse(&b"!"[..]), Ok((b'!', &b""[..])));
21
/// assert!(byte(b'A').parse(&b""[..]).is_err());
22
/// assert!(byte(b'A').parse(&b"!"[..]).is_err());
23
/// ```
24
0
pub fn byte<Input>(c: u8) -> Token<Input>
25
0
where
26
0
    Input: Stream<Token = u8>,
27
{
28
0
    token(c)
29
0
}
30
31
macro_rules! byte_parser {
32
    ($name:ident, $ty:ident, $f: ident) => {{
33
0
        satisfy(|c: u8| c.$f())
Unexecuted instantiation: combine::parser::byte::lower::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::space::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::upper::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::letter::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::alpha_num::<_>::{closure#0}
34
            .expected(stringify!($name))
35
    }};
36
    ($name:ident, $ty:ident, $f: ident $($args:tt)+) => {{
37
        satisfy(|c: u8| c.$f $($args)+)
38
            .expected(stringify!($name))
39
    }};
40
}
41
42
/// Parses a base-10 digit (0–9).
43
///
44
/// ```
45
/// use combine::Parser;
46
/// use combine::parser::byte::digit;
47
/// assert_eq!(digit().parse(&b"9"[..]), Ok((b'9', &b""[..])));
48
/// assert!(digit().parse(&b"A"[..]).is_err());
49
/// ```
50
0
pub fn digit<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
51
0
where
52
0
    Input: Stream<Token = u8>,
53
{
54
0
    byte_parser!(digit, Digit, is_ascii_digit())
55
0
}
56
57
/// Parses a `b' '`, `b'\t'`, `b'\n'` or `'b\'r'`.
58
///
59
/// ```
60
/// use combine::Parser;
61
/// use combine::parser::byte::space;
62
/// assert_eq!(space().parse(&b" "[..]), Ok((b' ', &b""[..])));
63
/// assert_eq!(space().parse(&b"  "[..]), Ok((b' ', &b" "[..])));
64
/// assert!(space().parse(&b"!"[..]).is_err());
65
/// assert!(space().parse(&b""[..]).is_err());
66
/// ```
67
0
pub fn space<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
68
0
where
69
0
    Input: Stream<Token = u8>,
70
{
71
0
    byte_parser!(space, Space, is_ascii_whitespace)
72
0
}
73
74
/// Skips over [`space`] zero or more times
75
///
76
/// [`space`]: fn.space.html
77
///
78
/// ```
79
/// use combine::Parser;
80
/// use combine::parser::byte::spaces;
81
/// assert_eq!(spaces().parse(&b""[..]), Ok(((), &b""[..])));
82
/// assert_eq!(spaces().parse(&b"   "[..]), Ok(((), &b""[..])));
83
/// ```
84
0
pub fn spaces<Input>() -> impl Parser<Input, Output = ()>
85
0
where
86
0
    Input: Stream<Token = u8>,
87
{
88
0
    skip_many(space()).expected("whitespaces")
89
0
}
90
91
/// Parses a newline byte (`b'\n'`).
92
///
93
/// ```
94
/// use combine::Parser;
95
/// use combine::parser::byte::newline;
96
/// assert_eq!(newline().parse(&b"\n"[..]), Ok((b'\n', &b""[..])));
97
/// assert!(newline().parse(&b"\r"[..]).is_err());
98
/// ```
99
150k
pub fn newline<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
100
150k
where
101
150k
    Input: Stream<Token = u8>,
102
{
103
150k
    satisfy(|ch: u8| ch == b'\n').expected("lf newline")
combine::parser::byte::newline::<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}
Line
Count
Source
103
138k
    satisfy(|ch: u8| ch == b'\n').expected("lf newline")
Unexecuted instantiation: combine::parser::byte::newline::<_>::{closure#0}
104
150k
}
combine::parser::byte::newline::<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
Line
Count
Source
99
150k
pub fn newline<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
100
150k
where
101
150k
    Input: Stream<Token = u8>,
102
{
103
150k
    satisfy(|ch: u8| ch == b'\n').expected("lf newline")
104
150k
}
Unexecuted instantiation: combine::parser::byte::newline::<_>
105
106
/// Parses carriage return and newline (`&b"\r\n"`), returning the newline byte.
107
///
108
/// ```
109
/// use combine::Parser;
110
/// use combine::parser::byte::crlf;
111
/// assert_eq!(crlf().parse(&b"\r\n"[..]), Ok((b'\n', &b""[..])));
112
/// assert!(crlf().parse(&b"\r"[..]).is_err());
113
/// assert!(crlf().parse(&b"\n"[..]).is_err());
114
/// ```
115
150k
pub fn crlf<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
116
150k
where
117
150k
    Input: Stream<Token = u8>,
118
{
119
150k
    no_partial(satisfy(|ch: u8| ch == b'\r').with(newline())).expected("crlf newline")
combine::parser::byte::crlf::<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}
Line
Count
Source
119
139k
    no_partial(satisfy(|ch: u8| ch == b'\r').with(newline())).expected("crlf newline")
Unexecuted instantiation: combine::parser::byte::crlf::<_>::{closure#0}
120
150k
}
combine::parser::byte::crlf::<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
Line
Count
Source
115
150k
pub fn crlf<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
116
150k
where
117
150k
    Input: Stream<Token = u8>,
118
{
119
150k
    no_partial(satisfy(|ch: u8| ch == b'\r').with(newline())).expected("crlf newline")
120
150k
}
Unexecuted instantiation: combine::parser::byte::crlf::<_>
121
122
/// Parses a tab byte (`b'\t'`).
123
///
124
/// ```
125
/// use combine::Parser;
126
/// use combine::parser::byte::tab;
127
/// assert_eq!(tab().parse(&b"\t"[..]), Ok((b'\t', &b""[..])));
128
/// assert!(tab().parse(&b" "[..]).is_err());
129
/// ```
130
0
pub fn tab<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
131
0
where
132
0
    Input: Stream<Token = u8>,
133
{
134
0
    satisfy(|ch| ch == b'\t').expected("tab")
135
0
}
136
137
/// Parses an uppercase ASCII letter (A–Z).
138
///
139
/// ```
140
/// use combine::Parser;
141
/// use combine::parser::byte::upper;
142
/// assert_eq!(upper().parse(&b"A"[..]), Ok((b'A', &b""[..])));
143
/// assert!(upper().parse(&b"a"[..]).is_err());
144
/// ```
145
0
pub fn upper<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
146
0
where
147
0
    Input: Stream<Token = u8>,
148
{
149
0
    byte_parser!(upper, Upper, is_ascii_uppercase)
150
0
}
151
152
/// Parses an lowercase ASCII letter (a–z).
153
///
154
/// ```
155
/// use combine::Parser;
156
/// use combine::parser::byte::lower;
157
/// assert_eq!(lower().parse(&b"a"[..]), Ok((b'a', &b""[..])));
158
/// assert!(lower().parse(&b"A"[..]).is_err());
159
/// ```
160
0
pub fn lower<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
161
0
where
162
0
    Input: Stream<Token = u8>,
163
{
164
0
    byte_parser!(lower, Lower, is_ascii_lowercase)
165
0
}
166
167
/// Parses either an ASCII alphabet letter or digit (a–z, A–Z, 0–9).
168
///
169
/// ```
170
/// use combine::Parser;
171
/// use combine::parser::byte::alpha_num;
172
/// assert_eq!(alpha_num().parse(&b"A"[..]), Ok((b'A', &b""[..])));
173
/// assert_eq!(alpha_num().parse(&b"1"[..]), Ok((b'1', &b""[..])));
174
/// assert!(alpha_num().parse(&b"!"[..]).is_err());
175
/// ```
176
0
pub fn alpha_num<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
177
0
where
178
0
    Input: Stream<Token = u8>,
179
{
180
0
    byte_parser!(alpha_num, AlphaNum, is_ascii_alphanumeric)
181
0
}
182
183
/// Parses an ASCII alphabet letter (a–z, A–Z).
184
///
185
/// ```
186
/// use combine::Parser;
187
/// use combine::parser::byte::letter;
188
/// assert_eq!(letter().parse(&b"a"[..]), Ok((b'a', &b""[..])));
189
/// assert_eq!(letter().parse(&b"A"[..]), Ok((b'A', &b""[..])));
190
/// assert!(letter().parse(&b"9"[..]).is_err());
191
/// ```
192
0
pub fn letter<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
193
0
where
194
0
    Input: Stream<Token = u8>,
195
{
196
0
    byte_parser!(letter, Letter, is_ascii_alphabetic)
197
0
}
198
199
/// Parses an octal digit.
200
///
201
/// ```
202
/// use combine::Parser;
203
/// use combine::parser::byte::oct_digit;
204
/// assert_eq!(oct_digit().parse(&b"7"[..]), Ok((b'7', &b""[..])));
205
/// assert!(oct_digit().parse(&b"8"[..]).is_err());
206
/// ```
207
0
pub fn oct_digit<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
208
0
where
209
0
    Input: Stream<Token = u8>,
210
{
211
0
    satisfy(|ch| (b'0'..=b'7').contains(&ch)).expected("octal digit")
212
0
}
213
214
/// Parses an ASCII hexdecimal digit (accepts both uppercase and lowercase).
215
///
216
/// ```
217
/// use combine::Parser;
218
/// use combine::parser::byte::hex_digit;
219
/// assert_eq!(hex_digit().parse(&b"F"[..]), Ok((b'F', &b""[..])));
220
/// assert!(hex_digit().parse(&b"H"[..]).is_err());
221
/// ```
222
0
pub fn hex_digit<Input>() -> impl Parser<Input, Output = u8, PartialState = ()>
223
0
where
224
0
    Input: Stream<Token = u8>,
225
{
226
0
    byte_parser!(hex_digit, HexDigit, is_ascii_hexdigit())
227
0
}
228
229
parser! {
230
/// Parses the bytes `s`.
231
///
232
/// If you have a stream implementing [`RangeStream`] such as `&[u8]` you can also use the
233
/// [`range`] parser which may be more efficient.
234
///
235
/// ```
236
/// # extern crate combine;
237
/// # use combine::*;
238
/// # use combine::parser::byte::bytes;
239
/// # fn main() {
240
/// let result = bytes(&b"rust"[..])
241
///     .parse(&b"rust"[..])
242
///     .map(|x| x.0);
243
/// assert_eq!(result, Ok(&b"rust"[..]));
244
/// # }
245
/// ```
246
///
247
/// [`RangeStream`]: super::super::stream::RangeStream
248
/// [`range`]: super::range::range
249
pub fn bytes['a, 'b, Input](s: &'static [u8])(Input) -> &'a [u8]
250
where [
251
    Input: Stream<Token = u8, Range = &'b [u8]>,
252
]
253
{
254
0
    bytes_cmp(s, |l: u8, r: u8| l == r)
Unexecuted instantiation: <combine::parser::byte::bytes<_> as combine::parser::Parser<_>>::parse_mode_impl::<_>::{closure#0}
Unexecuted instantiation: <combine::parser::byte::bytes<_> as combine::parser::Parser<_>>::add_committed_expected_error::{closure#0}
Unexecuted instantiation: <combine::parser::byte::bytes<_> as combine::parser::Parser<_>>::add_error::{closure#0}
255
}
256
}
257
258
parser! {
259
/// Parses the bytes `s` using `cmp` to compare each token.
260
///
261
/// If you have a stream implementing [`RangeStream`] such as `&[u8]` you can also use the
262
/// [`range`] parser which may be more efficient.
263
///
264
/// ```
265
/// # extern crate combine;
266
/// # use combine::*;
267
/// # use combine::parser::byte::bytes_cmp;
268
/// # use combine::stream::easy::Info;
269
/// # fn main() {
270
/// let result = bytes_cmp(&b"abc"[..], |l, r| l.eq_ignore_ascii_case(&r))
271
///     .parse(&b"AbC"[..]);
272
/// assert_eq!(result, Ok((&b"abc"[..], &b""[..])));
273
/// # }
274
/// ```
275
///
276
/// [`RangeStream`]: super::super::stream::RangeStream
277
/// [`range`]: super::range::range
278
pub fn bytes_cmp['a, 'b, C, Input](s: &'static [u8], cmp: C)(Input) -> &'a [u8]
279
where [
280
    C: FnMut(u8, u8) -> bool,
281
    Input: Stream<Token = u8, Range = &'b [u8]>,
282
]
283
{
284
    let s = *s;
285
    tokens_cmp(s.iter().cloned(), cmp)
286
        .map(move |_| s)
287
        .expected(error::Range(s))
288
}
289
}
290
291
macro_rules! take_until {
292
    (
293
        $(#[$attr:meta])*
294
        $type_name: ident, $func_name: ident, $memchr: ident, $($param: ident),+
295
    ) => {
296
        parser!{
297
            #[derive(Clone)]
298
            pub struct $type_name;
299
            type PartialState = usize;
300
            $(#[$attr])*
301
            pub fn $func_name[Input]($($param : u8),*)(Input) -> Input::Range
302
                where [
303
                    Input: RangeStream,
304
                    Input::Range: AsRef<[u8]> + crate::stream::Range,
305
                ]
306
            {
307
0
                take_fn(move |haystack: Input::Range| {
308
0
                    let haystack = haystack.as_ref();
309
0
                    match ::memchr::$memchr( $(*$param),+ , haystack) {
310
0
                        Some(i) => TakeRange::Found(i),
311
0
                        None => TakeRange::NotFound(haystack.len()),
312
                    }
313
0
                })
Unexecuted instantiation: <combine::parser::byte::TakeUntilByte<_> as combine::parser::Parser<_>>::parse_mode_impl::<_>::{closure#0}
Unexecuted instantiation: <combine::parser::byte::TakeUntilByte2<_> as combine::parser::Parser<_>>::parse_mode_impl::<_>::{closure#0}
Unexecuted instantiation: <combine::parser::byte::TakeUntilByte3<_> as combine::parser::Parser<_>>::parse_mode_impl::<_>::{closure#0}
Unexecuted instantiation: <combine::parser::byte::TakeUntilByte<_> as combine::parser::Parser<_>>::add_committed_expected_error::{closure#0}
Unexecuted instantiation: <combine::parser::byte::TakeUntilByte<_> as combine::parser::Parser<_>>::add_error::{closure#0}
Unexecuted instantiation: <combine::parser::byte::TakeUntilByte2<_> as combine::parser::Parser<_>>::add_committed_expected_error::{closure#0}
Unexecuted instantiation: <combine::parser::byte::TakeUntilByte2<_> as combine::parser::Parser<_>>::add_error::{closure#0}
Unexecuted instantiation: <combine::parser::byte::TakeUntilByte3<_> as combine::parser::Parser<_>>::add_committed_expected_error::{closure#0}
Unexecuted instantiation: <combine::parser::byte::TakeUntilByte3<_> as combine::parser::Parser<_>>::add_error::{closure#0}
314
            }
315
        }
316
    }
317
}
318
319
take_until! {
320
    /// Zero-copy parser which reads a range of 0 or more tokens until `a` is found.
321
    ///
322
    /// If `a` is not found, the parser will return an error.
323
    ///
324
    /// ```
325
    /// # extern crate combine;
326
    /// # use combine::parser::byte::take_until_byte;
327
    /// # use combine::*;
328
    /// # fn main() {
329
    /// let mut parser = take_until_byte(b'\r');
330
    /// let result = parser.parse("To: user@example.com\r\n");
331
    /// assert_eq!(result, Ok(("To: user@example.com", "\r\n")));
332
    /// let result = parser.parse("Hello, world\n");
333
    /// assert!(result.is_err());
334
    /// # }
335
    /// ```
336
    TakeUntilByte, take_until_byte, memchr, a
337
}
338
take_until! {
339
    /// Zero-copy parser which reads a range of 0 or more tokens until `a` or `b` is found.
340
    ///
341
    /// If `a` or `b` is not found, the parser will return an error.
342
    ///
343
    /// ```
344
    /// # extern crate combine;
345
    /// # use combine::parser::byte::take_until_byte2;
346
    /// # use combine::*;
347
    /// # fn main() {
348
    /// let mut parser = take_until_byte2(b'\r', b'\n');
349
    /// let result = parser.parse("To: user@example.com\r\n");
350
    /// assert_eq!(result, Ok(("To: user@example.com", "\r\n")));
351
    /// let result = parser.parse("Hello, world\n");
352
    /// assert_eq!(result, Ok(("Hello, world", "\n")));
353
    /// # }
354
    /// ```
355
    TakeUntilByte2, take_until_byte2, memchr2, a, b
356
}
357
take_until! {
358
    /// Zero-copy parser which reads a range of 0 or more tokens until `a`, 'b' or `c` is found.
359
    ///
360
    /// If `a`, 'b' or `c` is not found, the parser will return an error.
361
    ///
362
    /// ```
363
    /// # extern crate combine;
364
    /// # use combine::parser::byte::take_until_byte3;
365
    /// # use combine::*;
366
    /// # fn main() {
367
    /// let mut parser = take_until_byte3(b'\r', b'\n', b' ');
368
    /// let result = parser.parse("To: user@example.com\r\n");
369
    /// assert_eq!(result, Ok(("To:", " user@example.com\r\n")));
370
    /// let result = parser.parse("Helloworld");
371
    /// assert!(result.is_err());
372
    /// # }
373
    /// ```
374
    TakeUntilByte3, take_until_byte3, memchr3, a, b, c
375
}
376
377
parser! {
378
type PartialState = usize;
379
/// Zero-copy parser which reads a range of 0 or more tokens until `needle` is found.
380
///
381
/// If `a`, 'b' or `c` is not found, the parser will return an error.
382
///
383
/// Optimized variant of [`take_until_range`](../range/fn.take_until_range.html)
384
///
385
/// ```
386
/// use combine::*;
387
/// use combine::parser::byte::take_until_bytes;
388
/// assert_eq!(
389
///     take_until_bytes(&b"\r\n"[..]).easy_parse(&b"abc\r\n"[..]).map(|(x, _)| x),
390
///     Ok((&b"abc"[..]))
391
/// );
392
/// // Also works on strings as long as `needle` is UTF-8
393
/// assert_eq!(
394
///     take_until_bytes("\r\n".as_bytes()).easy_parse("abc\r\n").map(|(x, _)| x),
395
///     Ok(("abc"))
396
/// );
397
/// ```
398
pub fn take_until_bytes['a, Input](needle: &'a [u8])(Input) -> Input::Range
399
where [
400
    Input: RangeStream,
401
    Input::Range: AsRef<[u8]> + crate::stream::Range,
402
]
403
{
404
5.50M
    take_fn(move |haystack: Input::Range| {
405
5.50M
        let haystack = haystack.as_ref();
406
5.50M
        match memslice(needle, haystack) {
407
5.41M
            Some(i) => TakeRange::Found(i),
408
91.4k
            None => TakeRange::NotFound(haystack.len().saturating_sub(needle.len() - 1)),
409
        }
410
5.50M
    })
<combine::parser::byte::take_until_bytes<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::parse_mode_impl::<combine::parser::PartialMode>::{closure#0}
Line
Count
Source
404
92.5k
    take_fn(move |haystack: Input::Range| {
405
92.5k
        let haystack = haystack.as_ref();
406
92.5k
        match memslice(needle, haystack) {
407
71.7k
            Some(i) => TakeRange::Found(i),
408
20.8k
            None => TakeRange::NotFound(haystack.len().saturating_sub(needle.len() - 1)),
409
        }
410
92.5k
    })
<combine::parser::byte::take_until_bytes<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>> as combine::parser::Parser<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>>::parse_mode_impl::<combine::parser::FirstMode>::{closure#0}
Line
Count
Source
404
5.41M
    take_fn(move |haystack: Input::Range| {
405
5.41M
        let haystack = haystack.as_ref();
406
5.41M
        match memslice(needle, haystack) {
407
5.34M
            Some(i) => TakeRange::Found(i),
408
70.6k
            None => TakeRange::NotFound(haystack.len().saturating_sub(needle.len() - 1)),
409
        }
410
5.41M
    })
Unexecuted instantiation: <combine::parser::byte::take_until_bytes<_> as combine::parser::Parser<_>>::parse_mode_impl::<_>::{closure#0}
Unexecuted instantiation: <combine::parser::byte::take_until_bytes<_> as combine::parser::Parser<_>>::add_committed_expected_error::{closure#0}
Unexecuted instantiation: <combine::parser::byte::take_until_bytes<_> as combine::parser::Parser<_>>::add_error::{closure#0}
411
}
412
413
}
414
415
5.50M
fn memslice(needle: &[u8], haystack: &[u8]) -> Option<usize> {
416
5.50M
    let (&prefix, suffix) = match needle.split_first() {
417
5.50M
        Some(x) => x,
418
0
        None => return Some(0),
419
    };
420
53.6M
    for i in memchr::memchr_iter(prefix, haystack) {
421
53.6M
        if haystack[i + 1..].starts_with(suffix) {
422
5.41M
            return Some(i);
423
48.2M
        }
424
    }
425
91.4k
    None
426
5.50M
}
427
428
/// Parsers for decoding numbers in big-endian or little-endian order.
429
pub mod num {
430
431
    use crate::{error::ResultExt, lib::mem::size_of, parser::function::parser, stream::uncons};
432
433
    use super::*;
434
435
    macro_rules! integer_parser {
436
        (
437
            $(#[$attr:meta])*
438
            pub $type_name: ident,
439
            $output_type: ident, $be_name: ident, $le_name: ident, $read_name: ident
440
        ) => {
441
            $(#[$attr])*
442
0
            pub fn $be_name<'a, Input>() -> impl Parser<Input, Output = $output_type, PartialState = ()>
443
0
            where
444
0
                Input: Stream<Token = u8>,
445
            {
446
0
                parser(|input: &mut Input| {
447
0
                    let checkpoint = input.checkpoint();
448
0
                    let result = (|input: &mut Input| {
449
0
                        let mut buffer = [0u8; size_of::<$output_type>()];
450
0
                        for elem in &mut buffer[..] {
451
0
                            *elem = ctry!(uncons(input)).0;
452
                        }
453
0
                        CommitOk($output_type::from_be_bytes(buffer))
Unexecuted instantiation: combine::parser::byte::num::be_f32::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_f64::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_i16::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_i32::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_i64::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_u16::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_u32::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_u64::<_>::{closure#0}::{closure#0}
454
0
                    })(input);
455
0
                    if result.is_err() {
456
0
                        input.reset(checkpoint).committed().into_result()?;
457
0
                    }
458
0
                    result.into_result()
459
0
                })
Unexecuted instantiation: combine::parser::byte::num::be_f32::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_f64::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_i16::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_i32::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_i64::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_u16::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_u32::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::be_u64::<_>::{closure#0}
460
0
            }
Unexecuted instantiation: combine::parser::byte::num::be_f32::<_>
Unexecuted instantiation: combine::parser::byte::num::be_f64::<_>
Unexecuted instantiation: combine::parser::byte::num::be_i16::<_>
Unexecuted instantiation: combine::parser::byte::num::be_i32::<_>
Unexecuted instantiation: combine::parser::byte::num::be_i64::<_>
Unexecuted instantiation: combine::parser::byte::num::be_u16::<_>
Unexecuted instantiation: combine::parser::byte::num::be_u32::<_>
Unexecuted instantiation: combine::parser::byte::num::be_u64::<_>
461
462
            $(#[$attr])*
463
0
            pub fn $le_name<'a, Input>() -> impl Parser<Input, Output = $output_type, PartialState = ()>
464
0
            where
465
0
                Input: Stream<Token = u8>,
466
            {
467
0
                parser(|input: &mut Input| {
468
0
                    let checkpoint = input.checkpoint();
469
0
                    let result = (|input: &mut Input| {
470
0
                        let mut buffer = [0u8; size_of::<$output_type>()];
471
0
                        for elem in &mut buffer[..] {
472
0
                            *elem = ctry!(uncons(input)).0;
473
                        }
474
0
                        CommitOk($output_type::from_le_bytes(buffer))
Unexecuted instantiation: combine::parser::byte::num::le_f32::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_f64::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_i16::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_i32::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_i64::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_u16::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_u32::<_>::{closure#0}::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_u64::<_>::{closure#0}::{closure#0}
475
0
                    })(input);
476
0
                    if result.is_err() {
477
0
                        input.reset(checkpoint).committed().into_result()?;
478
0
                    }
479
0
                    result.into_result()
480
0
                })
Unexecuted instantiation: combine::parser::byte::num::le_f32::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_f64::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_i16::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_i32::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_i64::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_u16::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_u32::<_>::{closure#0}
Unexecuted instantiation: combine::parser::byte::num::le_u64::<_>::{closure#0}
481
0
            }
Unexecuted instantiation: combine::parser::byte::num::le_f32::<_>
Unexecuted instantiation: combine::parser::byte::num::le_f64::<_>
Unexecuted instantiation: combine::parser::byte::num::le_i16::<_>
Unexecuted instantiation: combine::parser::byte::num::le_i32::<_>
Unexecuted instantiation: combine::parser::byte::num::le_i64::<_>
Unexecuted instantiation: combine::parser::byte::num::le_u16::<_>
Unexecuted instantiation: combine::parser::byte::num::le_u32::<_>
Unexecuted instantiation: combine::parser::byte::num::le_u64::<_>
482
        }
483
    }
484
485
    integer_parser!(
486
        /// Reads a u16 out of the byte stream with the specified endianess
487
        ///
488
        /// ```
489
        /// use combine::Parser;
490
        /// use combine::parser::byte::num::le_u16;
491
        ///
492
        /// assert_eq!(le_u16().parse(&b"\x01\0"[..]), Ok((1, &b""[..])));
493
        /// assert!(le_u16().parse(&b"\0"[..]).is_err());
494
        /// ```
495
        pub U16, u16, be_u16, le_u16, read_u16
496
    );
497
    integer_parser!(
498
        /// Reads a u32 out of the byte stream with the specified endianess
499
        ///
500
        /// ```
501
        /// use combine::Parser;
502
        /// use combine::parser::byte::num::le_u32;
503
        ///
504
        /// assert_eq!(le_u32().parse(&b"\x01\0\0\0"[..]), Ok((1, &b""[..])));
505
        /// assert!(le_u32().parse(&b"\x01\0\0"[..]).is_err());
506
        /// ```
507
        pub U32, u32, be_u32, le_u32, read_u32
508
    );
509
    integer_parser!(
510
        /// Reads a u64 out of the byte stream with the specified endianess
511
        ///
512
        /// ```
513
        /// use combine::Parser;
514
        /// use combine::parser::byte::num::le_u64;
515
        ///
516
        /// assert_eq!(le_u64().parse(&b"\x01\0\0\0\0\0\0\0"[..]), Ok((1, &b""[..])));
517
        /// assert!(le_u64().parse(&b"\x01\0\0\0\0\0\0"[..]).is_err());
518
        /// ```
519
        pub U64, u64, be_u64, le_u64, read_u64
520
    );
521
522
    integer_parser!(
523
        /// Reads a i16 out of the byte stream with the specified endianess
524
        ///
525
        /// ```
526
        /// use combine::Parser;
527
        /// use combine::parser::byte::num::le_i16;
528
        ///
529
        /// assert_eq!(le_i16().parse(&b"\x01\0"[..]), Ok((1, &b""[..])));
530
        /// assert!(le_i16().parse(&b"\x01"[..]).is_err());
531
        /// ```
532
        pub I16, i16, be_i16, le_i16, read_i16
533
    );
534
535
    integer_parser!(
536
        /// Reads a i32 out of the byte stream with the specified endianess
537
        ///
538
        /// ```
539
        /// use combine::Parser;
540
        /// use combine::parser::byte::num::le_i32;
541
        ///
542
        /// assert_eq!(le_i32().parse(&b"\x01\0\0\0"[..]), Ok((1, &b""[..])));
543
        /// assert!(le_i32().parse(&b"\x01\0\0"[..]).is_err());
544
        /// ```
545
        pub I32, i32, be_i32, le_i32, read_i32
546
    );
547
    integer_parser!(
548
        /// Reads a i64 out of the byte stream with the specified endianess
549
        ///
550
        /// ```
551
        /// use combine::Parser;
552
        /// use combine::parser::byte::num::le_i64;
553
        ///
554
        /// assert_eq!(le_i64().parse(&b"\x01\0\0\0\0\0\0\0"[..]), Ok((1, &b""[..])));
555
        /// assert!(le_i64().parse(&b"\x01\0\0\0\0\0\0"[..]).is_err());
556
        /// ```
557
        pub I64, i64, be_i64, le_i64, read_i64
558
    );
559
560
    integer_parser!(
561
        /// Reads a i32 out of the byte stream with the specified endianess
562
        ///
563
        /// ```
564
        /// use combine::Parser;
565
        /// use combine::parser::byte::num::le_f32;
566
        ///
567
        /// let buf = 123.45f32.to_le_bytes();
568
        /// assert_eq!(le_f32().parse(&buf[..]), Ok((123.45, &b""[..])));
569
        /// assert!(le_f32().parse(&b"\x01\0\0"[..]).is_err());
570
        /// ```
571
        pub F32, f32, be_f32, le_f32, read_f32
572
    );
573
    integer_parser!(
574
        /// Reads a i64 out of the byte stream with the specified endianess
575
        ///
576
        /// ```
577
        /// use combine::Parser;
578
        /// use combine::parser::byte::num::le_f64;
579
        ///
580
        /// let buf = 123.45f64.to_le_bytes();
581
        /// assert_eq!(le_f64().parse(&buf[..]), Ok((123.45, &b""[..])));
582
        /// assert!(le_f64().parse(&b"\x01\0\0\0\0\0\0"[..]).is_err());
583
        /// ```
584
        pub F64, f64, be_f64, le_f64, read_f64
585
    );
586
587
    #[cfg(all(feature = "std", test))]
588
    mod tests {
589
590
        use crate::stream::{buffered, position, IteratorStream};
591
592
        use super::*;
593
594
        #[test]
595
        fn no_rangestream() {
596
            let buf = 123.45f64.to_le_bytes();
597
            assert_eq!(
598
                le_f64()
599
                    .parse(buffered::Stream::new(
600
                        position::Stream::new(IteratorStream::new(buf.iter().cloned())),
601
                        1
602
                    ))
603
                    .map(|(t, _)| t),
604
                Ok(123.45)
605
            );
606
            assert_eq!(
607
                le_f64()
608
                    .parse(buffered::Stream::new(
609
                        position::Stream::new(IteratorStream::new(buf.iter().cloned())),
610
                        1
611
                    ))
612
                    .map(|(t, _)| t),
613
                Ok(123.45)
614
            );
615
            let buf = 123.45f64.to_be_bytes();
616
            assert_eq!(
617
                be_f64()
618
                    .parse(buffered::Stream::new(
619
                        position::Stream::new(IteratorStream::new(buf.iter().cloned())),
620
                        1
621
                    ))
622
                    .map(|(t, _)| t),
623
                Ok(123.45)
624
            );
625
        }
626
    }
627
}
628
629
#[cfg(all(feature = "std", test))]
630
mod tests {
631
632
    use crate::stream::{buffered, position, read};
633
634
    use super::*;
635
636
    #[test]
637
    fn memslice_basic() {
638
        let haystack = b"abc123";
639
        assert_eq!(memslice(b"", haystack), Some(0));
640
        assert_eq!(memslice(b"a", haystack), Some(0));
641
        assert_eq!(memslice(b"ab", haystack), Some(0));
642
        assert_eq!(memslice(b"c12", haystack), Some(2));
643
644
        let haystack2 = b"abcab2";
645
        assert_eq!(memslice(b"abc", haystack2), Some(0));
646
        assert_eq!(memslice(b"ab2", haystack2), Some(3));
647
648
        let haystack3 = b"aaabaaaa";
649
        assert_eq!(memslice(b"aaaa", haystack3), Some(4));
650
    }
651
652
    #[test]
653
    fn bytes_read_stream() {
654
        assert!(bytes(b"abc")
655
            .parse(buffered::Stream::new(
656
                position::Stream::new(read::Stream::new("abc".as_bytes())),
657
                1
658
            ))
659
            .is_ok());
660
    }
661
}