Coverage Report

Created: 2026-08-31 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/combine-4.6.8/src/stream/mod.rs
Line
Count
Source
1
//
2
//Traits and implementations of arbitrary data streams.
3
//!
4
//! Streams are similar to the `Iterator` trait in that they represent some sequential set of items
5
//! which can be retrieved one by one. Where `Stream`s differ is that they are allowed to return
6
//! errors instead of just `None` and if they implement the `RangeStreamOnce` trait they are also
7
//! capable of returning multiple items at the same time, usually in the form of a slice.
8
//!
9
//! In addition to he functionality above, a proper `Stream` usable by a `Parser` must also have a
10
//! position (marked by the `Positioned` trait) and must also be resetable (marked by the
11
//! `ResetStream` trait). The former is used to ensure that errors at different points in the stream
12
//! aren't combined and the latter is used in parsers such as `or` to try multiple alternative
13
//! parses.
14
15
use crate::lib::{cmp::Ordering, fmt, marker::PhantomData, str::Chars};
16
17
use crate::{
18
    error::{
19
        ParseError,
20
        ParseResult::{self, *},
21
        StreamError, StringStreamError, Tracked, UnexpectedParse,
22
    },
23
    Parser,
24
};
25
26
#[cfg(feature = "std")]
27
pub use self::decoder::Decoder;
28
29
#[doc(hidden)]
30
#[macro_export]
31
macro_rules! clone_resetable {
32
    (( $($params: tt)* ) $ty: ty) => {
33
        impl<$($params)*> ResetStream for $ty
34
            where Self: StreamOnce
35
        {
36
            type Checkpoint = Self;
37
38
60.4M
            fn checkpoint(&self) -> Self {
39
0
                self.clone()
40
60.4M
            }
<&[u8] as combine::stream::ResetStream>::checkpoint
Line
Count
Source
38
60.4M
            fn checkpoint(&self) -> Self {
39
60.4M
                self.clone()
40
60.4M
            }
Unexecuted instantiation: <&str as combine::stream::ResetStream>::checkpoint
Unexecuted instantiation: <&[_] as combine::stream::ResetStream>::checkpoint
Unexecuted instantiation: <combine::stream::SliceStream<_> as combine::stream::ResetStream>::checkpoint
Unexecuted instantiation: <combine::stream::IteratorStream<_> as combine::stream::ResetStream>::checkpoint
41
            #[inline]
42
16.4M
            fn reset(&mut self, checkpoint: Self) -> Result<(), Self::Error> {
43
0
                *self = checkpoint;
44
16.4M
                Ok(())
45
16.4M
            }
<&[u8] as combine::stream::ResetStream>::reset
Line
Count
Source
42
16.4M
            fn reset(&mut self, checkpoint: Self) -> Result<(), Self::Error> {
43
16.4M
                *self = checkpoint;
44
16.4M
                Ok(())
45
16.4M
            }
Unexecuted instantiation: <&[_] as combine::stream::ResetStream>::reset
Unexecuted instantiation: <combine::stream::SliceStream<_> as combine::stream::ResetStream>::reset
Unexecuted instantiation: <combine::stream::IteratorStream<_> as combine::stream::ResetStream>::reset
Unexecuted instantiation: <&str as combine::stream::ResetStream>::reset
46
        }
47
    }
48
}
49
50
#[cfg(feature = "std")]
51
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
52
pub mod buf_reader;
53
/// Stream wrapper which provides a `ResetStream` impl for `StreamOnce` impls which do not have
54
/// one.
55
#[cfg(feature = "alloc")]
56
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
57
pub mod buffered;
58
#[cfg(feature = "std")]
59
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
60
pub mod easy;
61
/// Stream wrapper which provides more detailed position information.
62
pub mod position;
63
/// Stream wrapper allowing `std::io::Read` to be used
64
#[cfg(feature = "std")]
65
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
66
pub mod read;
67
pub mod span;
68
/// Stream wrapper allowing custom state to be used.
69
pub mod state;
70
71
#[cfg(feature = "std")]
72
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
73
pub mod decoder;
74
75
/// A type which has a position.
76
pub trait Positioned: StreamOnce {
77
    /// Returns the current position of the stream.
78
    fn position(&self) -> Self::Position;
79
}
80
81
/// Convenience alias over the `StreamError` for the input stream `Input`
82
///
83
/// ```
84
/// #[macro_use]
85
/// extern crate combine;
86
/// use combine::{easy, Parser, Stream, many1};
87
/// use combine::parser::char::letter;
88
/// use combine::stream::StreamErrorFor;
89
/// use combine::error::{ParseError, StreamError};
90
///
91
/// parser!{
92
///    fn parser[Input]()(Input) -> String
93
///     where [ Input: Stream<Token = char>, ]
94
///     {
95
///         many1(letter()).and_then(|word: String| {
96
///             if word == "combine" {
97
///                 Ok(word)
98
///             } else {
99
///                 // The alias makes it easy to refer to the `StreamError` type of `Input`
100
///                 Err(StreamErrorFor::<Input>::expected_static_message("combine"))
101
///             }
102
///         })
103
///     }
104
/// }
105
///
106
/// fn main() {
107
/// }
108
/// ```
109
pub type StreamErrorFor<Input> = <<Input as StreamOnce>::Error as ParseError<
110
    <Input as StreamOnce>::Token,
111
    <Input as StreamOnce>::Range,
112
    <Input as StreamOnce>::Position,
113
>>::StreamError;
114
115
/// `StreamOnce` represents a sequence of items that can be extracted one by one.
116
pub trait StreamOnce {
117
    /// The type of items which is yielded from this stream.
118
    type Token: Clone;
119
120
    /// The type of a range of items yielded from this stream.
121
    /// Types which do not a have a way of yielding ranges of items should just use the
122
    /// `Self::Token` for this type.
123
    type Range: Clone;
124
125
    /// Type which represents the position in a stream.
126
    /// `Ord` is required to allow parsers to determine which of two positions are further ahead.
127
    type Position: Clone + Ord;
128
129
    type Error: ParseError<Self::Token, Self::Range, Self::Position>;
130
    /// Takes a stream and removes its first token, yielding the token and the rest of the elements.
131
    /// Returns `Err` if no element could be retrieved.
132
    fn uncons(&mut self) -> Result<Self::Token, StreamErrorFor<Self>>;
133
134
    /// Returns `true` if this stream only contains partial input.
135
    ///
136
    /// See `PartialStream`.
137
0
    fn is_partial(&self) -> bool {
138
0
        false
139
0
    }
140
}
141
142
/// A `StreamOnce` which can create checkpoints which the stream can be reset to
143
pub trait ResetStream: StreamOnce {
144
    type Checkpoint: Clone;
145
146
    /// Creates a `Checkpoint` at the current position which can be used to reset the stream
147
    /// later to the current position
148
    fn checkpoint(&self) -> Self::Checkpoint;
149
    /// Attempts to reset the stream to an earlier position.
150
    fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), Self::Error>;
151
}
152
153
clone_resetable! {('a) &'a str}
154
clone_resetable! {('a, T) &'a [T]}
155
clone_resetable! {('a, T) SliceStream<'a, T> }
156
clone_resetable! {(T: Clone) IteratorStream<T>}
157
158
/// A stream of tokens which can be duplicated
159
///
160
/// This is a trait over types which implement the `StreamOnce`, `ResetStream` and `Positioned`
161
/// traits. If you need a custom `Stream` object then implement those traits and `Stream` is
162
/// implemented automatically.
163
pub trait Stream: StreamOnce + ResetStream + Positioned {}
164
165
impl<Input> Stream for Input
166
where
167
    Input: StreamOnce + Positioned + ResetStream,
168
{
169
}
170
171
#[inline]
172
8.50M
pub fn uncons<Input>(input: &mut Input) -> ParseResult<Input::Token, Input::Error>
173
8.50M
where
174
8.50M
    Input: ?Sized + Stream,
175
{
176
8.50M
    match input.uncons() {
177
8.49M
        Ok(x) => CommitOk(x),
178
12.0k
        Err(err) => wrap_stream_error(input, err),
179
    }
180
8.50M
}
combine::stream::uncons::<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
Line
Count
Source
172
8.50M
pub fn uncons<Input>(input: &mut Input) -> ParseResult<Input::Token, Input::Error>
173
8.50M
where
174
8.50M
    Input: ?Sized + Stream,
175
{
176
8.50M
    match input.uncons() {
177
8.49M
        Ok(x) => CommitOk(x),
178
12.0k
        Err(err) => wrap_stream_error(input, err),
179
    }
180
8.50M
}
Unexecuted instantiation: combine::stream::uncons::<_>
181
182
/// A `RangeStream` is an extension of `StreamOnce` which allows for zero copy parsing.
183
pub trait RangeStreamOnce: StreamOnce + ResetStream {
184
    /// Takes `size` elements from the stream.
185
    /// Fails if the length of the stream is less than `size`.
186
    fn uncons_range(&mut self, size: usize) -> Result<Self::Range, StreamErrorFor<Self>>;
187
188
    /// Takes items from stream, testing each one with `predicate`.
189
    /// returns the range of items which passed `predicate`.
190
    fn uncons_while<F>(&mut self, f: F) -> Result<Self::Range, StreamErrorFor<Self>>
191
    where
192
        F: FnMut(Self::Token) -> bool;
193
194
    #[inline]
195
    /// Takes items from stream, testing each one with `predicate`
196
    /// returns a range of at least one items which passed `predicate`.
197
    ///
198
    /// # Note
199
    ///
200
    /// This may not return `PeekOk` as it should uncons at least one token.
201
0
    fn uncons_while1<F>(&mut self, mut f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>>
202
0
    where
203
0
        F: FnMut(Self::Token) -> bool,
204
    {
205
0
        let mut committed = false;
206
0
        let mut started_at_eoi = true;
207
0
        let result = self.uncons_while(|c| {
208
0
            let ok = f(c);
209
0
            committed |= ok;
210
0
            started_at_eoi = false;
211
0
            ok
212
0
        });
213
0
        if committed {
214
0
            match result {
215
0
                Ok(x) => CommitOk(x),
216
0
                Err(x) => CommitErr(x),
217
            }
218
0
        } else if started_at_eoi {
219
0
            PeekErr(Tracked::from(StreamErrorFor::<Self>::end_of_input()))
220
        } else {
221
0
            PeekErr(Tracked::from(
222
0
                StreamErrorFor::<Self>::unexpected_static_message(""),
223
0
            ))
224
        }
225
0
    }
226
227
    /// Returns the distance between `self` and `end`. The returned `usize` must be so that
228
    ///
229
    /// ```ignore
230
    /// let start = stream.checkpoint();
231
    /// stream.uncons_range(distance);
232
    /// stream.distance(&start) == distance
233
    /// ```
234
    fn distance(&self, end: &Self::Checkpoint) -> usize;
235
236
    /// Returns the entire range of `self`
237
    fn range(&self) -> Self::Range;
238
}
239
240
/// A `RangeStream` is an extension of `Stream` which allows for zero copy parsing.
241
pub trait RangeStream: Stream + RangeStreamOnce {}
242
243
impl<Input> RangeStream for Input where Input: RangeStreamOnce + Stream {}
244
245
#[doc(hidden)]
246
16.8k
pub fn wrap_stream_error<T, Input>(
247
16.8k
    input: &Input,
248
16.8k
    err: <Input::Error as ParseError<Input::Token, Input::Range, Input::Position>>::StreamError,
249
16.8k
) -> ParseResult<T, <Input as StreamOnce>::Error>
250
16.8k
where
251
16.8k
    Input: ?Sized + StreamOnce + Positioned,
252
{
253
16.8k
    let err = Input::Error::from_error(input.position(), err);
254
16.8k
    if input.is_partial() {
255
14.8k
        CommitErr(err)
256
    } else {
257
1.95k
        PeekErr(err.into())
258
    }
259
16.8k
}
combine::stream::wrap_stream_error::<&[u8], combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
Line
Count
Source
246
4.79k
pub fn wrap_stream_error<T, Input>(
247
4.79k
    input: &Input,
248
4.79k
    err: <Input::Error as ParseError<Input::Token, Input::Range, Input::Position>>::StreamError,
249
4.79k
) -> ParseResult<T, <Input as StreamOnce>::Error>
250
4.79k
where
251
4.79k
    Input: ?Sized + StreamOnce + Positioned,
252
{
253
4.79k
    let err = Input::Error::from_error(input.position(), err);
254
4.79k
    if input.is_partial() {
255
4.44k
        CommitErr(err)
256
    } else {
257
342
        PeekErr(err.into())
258
    }
259
4.79k
}
combine::stream::wrap_stream_error::<u8, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
Line
Count
Source
246
12.0k
pub fn wrap_stream_error<T, Input>(
247
12.0k
    input: &Input,
248
12.0k
    err: <Input::Error as ParseError<Input::Token, Input::Range, Input::Position>>::StreamError,
249
12.0k
) -> ParseResult<T, <Input as StreamOnce>::Error>
250
12.0k
where
251
12.0k
    Input: ?Sized + StreamOnce + Positioned,
252
{
253
12.0k
    let err = Input::Error::from_error(input.position(), err);
254
12.0k
    if input.is_partial() {
255
10.4k
        CommitErr(err)
256
    } else {
257
1.61k
        PeekErr(err.into())
258
    }
259
12.0k
}
Unexecuted instantiation: combine::stream::wrap_stream_error::<_, _>
260
261
#[inline]
262
24.6M
pub fn uncons_range<Input>(
263
24.6M
    input: &mut Input,
264
24.6M
    size: usize,
265
24.6M
) -> ParseResult<Input::Range, <Input as StreamOnce>::Error>
266
24.6M
where
267
24.6M
    Input: ?Sized + RangeStream,
268
{
269
24.6M
    match input.uncons_range(size) {
270
4.79k
        Err(err) => wrap_stream_error(input, err),
271
24.6M
        Ok(x) => {
272
24.6M
            if size == 0 {
273
6.11M
                PeekOk(x)
274
            } else {
275
18.5M
                CommitOk(x)
276
            }
277
        }
278
    }
279
24.6M
}
combine::stream::uncons_range::<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
Line
Count
Source
262
24.6M
pub fn uncons_range<Input>(
263
24.6M
    input: &mut Input,
264
24.6M
    size: usize,
265
24.6M
) -> ParseResult<Input::Range, <Input as StreamOnce>::Error>
266
24.6M
where
267
24.6M
    Input: ?Sized + RangeStream,
268
{
269
24.6M
    match input.uncons_range(size) {
270
4.79k
        Err(err) => wrap_stream_error(input, err),
271
24.6M
        Ok(x) => {
272
24.6M
            if size == 0 {
273
6.11M
                PeekOk(x)
274
            } else {
275
18.5M
                CommitOk(x)
276
            }
277
        }
278
    }
279
24.6M
}
Unexecuted instantiation: combine::stream::uncons_range::<_>
280
281
#[doc(hidden)]
282
1.23k
pub fn input_at_eof<Input>(input: &mut Input) -> bool
283
1.23k
where
284
1.23k
    Input: ?Sized + Stream,
285
{
286
1.23k
    let before = input.checkpoint();
287
1.23k
    let x = input
288
1.23k
        .uncons()
289
1.23k
        .err()
290
1.23k
        .map_or(false, |err| err.is_unexpected_end_of_input());
combine::stream::input_at_eof::<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}
Line
Count
Source
290
773
        .map_or(false, |err| err.is_unexpected_end_of_input());
Unexecuted instantiation: combine::stream::input_at_eof::<_>::{closure#0}
291
1.23k
    input.reset(before).is_ok() && x
292
1.23k
}
combine::stream::input_at_eof::<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
Line
Count
Source
282
1.23k
pub fn input_at_eof<Input>(input: &mut Input) -> bool
283
1.23k
where
284
1.23k
    Input: ?Sized + Stream,
285
{
286
1.23k
    let before = input.checkpoint();
287
1.23k
    let x = input
288
1.23k
        .uncons()
289
1.23k
        .err()
290
1.23k
        .map_or(false, |err| err.is_unexpected_end_of_input());
291
1.23k
    input.reset(before).is_ok() && x
292
1.23k
}
Unexecuted instantiation: combine::stream::input_at_eof::<_>
293
294
/// Removes items from the input while `predicate` returns `true`.
295
#[inline]
296
0
pub fn uncons_while<Input, F>(
297
0
    input: &mut Input,
298
0
    predicate: F,
299
0
) -> ParseResult<Input::Range, Input::Error>
300
0
where
301
0
    F: FnMut(Input::Token) -> bool,
302
0
    Input: ?Sized + RangeStream,
303
0
    Input::Range: Range,
304
{
305
0
    match input.uncons_while(predicate) {
306
0
        Err(err) => wrap_stream_error(input, err),
307
0
        Ok(x) => {
308
0
            if input.is_partial() && input_at_eof(input) {
309
                // Partial inputs which encounter end of file must fail to let more input be
310
                // retrieved
311
0
                CommitErr(Input::Error::from_error(
312
0
                    input.position(),
313
0
                    StreamError::end_of_input(),
314
0
                ))
315
0
            } else if x.len() == 0 {
316
0
                PeekOk(x)
317
            } else {
318
0
                CommitOk(x)
319
            }
320
        }
321
    }
322
0
}
323
324
#[inline]
325
/// Takes items from stream, testing each one with `predicate`
326
/// returns a range of at least one items which passed `predicate`.
327
///
328
/// # Note
329
///
330
/// This may not return `PeekOk` as it should uncons at least one token.
331
0
pub fn uncons_while1<Input, F>(
332
0
    input: &mut Input,
333
0
    predicate: F,
334
0
) -> ParseResult<Input::Range, Input::Error>
335
0
where
336
0
    F: FnMut(Input::Token) -> bool,
337
0
    Input: ?Sized + RangeStream,
338
{
339
0
    match input.uncons_while1(predicate) {
340
0
        CommitOk(x) => {
341
0
            if input.is_partial() && input_at_eof(input) {
342
                // Partial inputs which encounter end of file must fail to let more input be
343
                // retrieved
344
0
                CommitErr(Input::Error::from_error(
345
0
                    input.position(),
346
0
                    StreamError::end_of_input(),
347
0
                ))
348
            } else {
349
0
                CommitOk(x)
350
            }
351
        }
352
        PeekErr(_) => {
353
0
            if input.is_partial() && input_at_eof(input) {
354
                // Partial inputs which encounter end of file must fail to let more input be
355
                // retrieved
356
0
                CommitErr(Input::Error::from_error(
357
0
                    input.position(),
358
0
                    StreamError::end_of_input(),
359
0
                ))
360
            } else {
361
0
                PeekErr(Input::Error::empty(input.position()).into())
362
            }
363
        }
364
0
        CommitErr(err) => {
365
0
            if input.is_partial() && input_at_eof(input) {
366
                // Partial inputs which encounter end of file must fail to let more input be
367
                // retrieved
368
0
                CommitErr(Input::Error::from_error(
369
0
                    input.position(),
370
0
                    StreamError::end_of_input(),
371
0
                ))
372
            } else {
373
0
                wrap_stream_error(input, err)
374
            }
375
        }
376
0
        PeekOk(_) => unreachable!(),
377
    }
378
0
}
379
380
/// Trait representing a range of elements.
381
pub trait Range {
382
    /// Returns the remaining length of `self`.
383
    /// The returned length need not be the same as the number of items left in the stream.
384
    fn len(&self) -> usize;
385
386
    /// Returns `true` if the range does not contain any elements (`Range::len() == 0`)
387
1.66k
    fn is_empty(&self) -> bool {
388
1.66k
        self.len() == 0
389
1.66k
    }
<&[u8] as combine::stream::Range>::is_empty
Line
Count
Source
387
1.66k
    fn is_empty(&self) -> bool {
388
1.66k
        self.len() == 0
389
1.66k
    }
Unexecuted instantiation: <_ as combine::stream::Range>::is_empty
390
}
391
392
impl<'a, I> StreamOnce for &'a mut I
393
where
394
    I: StreamOnce + ?Sized,
395
{
396
    type Token = I::Token;
397
398
    type Range = I::Range;
399
400
    type Position = I::Position;
401
402
    type Error = I::Error;
403
0
    fn uncons(&mut self) -> Result<Self::Token, StreamErrorFor<Self>> {
404
0
        (**self).uncons()
405
0
    }
406
407
241k
    fn is_partial(&self) -> bool {
408
241k
        (**self).is_partial()
409
241k
    }
<&mut combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>> as combine::stream::StreamOnce>::is_partial
Line
Count
Source
407
241k
    fn is_partial(&self) -> bool {
408
241k
        (**self).is_partial()
409
241k
    }
Unexecuted instantiation: <&mut _ as combine::stream::StreamOnce>::is_partial
410
}
411
412
impl<'a, I> Positioned for &'a mut I
413
where
414
    I: Positioned + ?Sized,
415
{
416
    #[inline]
417
0
    fn position(&self) -> Self::Position {
418
0
        (**self).position()
419
0
    }
420
}
421
422
impl<'a, I> ResetStream for &'a mut I
423
where
424
    I: ResetStream + ?Sized,
425
{
426
    type Checkpoint = I::Checkpoint;
427
428
9.38M
    fn checkpoint(&self) -> Self::Checkpoint {
429
9.38M
        (**self).checkpoint()
430
9.38M
    }
<&mut combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>> as combine::stream::ResetStream>::checkpoint
Line
Count
Source
428
9.38M
    fn checkpoint(&self) -> Self::Checkpoint {
429
9.38M
        (**self).checkpoint()
430
9.38M
    }
Unexecuted instantiation: <&mut _ as combine::stream::ResetStream>::checkpoint
431
432
0
    fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), Self::Error> {
433
0
        (**self).reset(checkpoint)
434
0
    }
435
}
436
437
impl<'a, I> RangeStreamOnce for &'a mut I
438
where
439
    I: RangeStreamOnce + ?Sized,
440
{
441
    #[inline]
442
0
    fn uncons_while<F>(&mut self, f: F) -> Result<Self::Range, StreamErrorFor<Self>>
443
0
    where
444
0
        F: FnMut(Self::Token) -> bool,
445
    {
446
0
        (**self).uncons_while(f)
447
0
    }
448
449
    #[inline]
450
0
    fn uncons_while1<F>(&mut self, f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>>
451
0
    where
452
0
        F: FnMut(Self::Token) -> bool,
453
    {
454
0
        (**self).uncons_while1(f)
455
0
    }
456
457
    #[inline]
458
0
    fn uncons_range(&mut self, size: usize) -> Result<Self::Range, StreamErrorFor<Self>> {
459
0
        (**self).uncons_range(size)
460
0
    }
461
462
    #[inline]
463
48.7k
    fn distance(&self, end: &Self::Checkpoint) -> usize {
464
48.7k
        (**self).distance(end)
465
48.7k
    }
<&mut combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>> as combine::stream::RangeStreamOnce>::distance
Line
Count
Source
463
48.7k
    fn distance(&self, end: &Self::Checkpoint) -> usize {
464
48.7k
        (**self).distance(end)
465
48.7k
    }
Unexecuted instantiation: <&mut _ as combine::stream::RangeStreamOnce>::distance
466
467
0
    fn range(&self) -> Self::Range {
468
0
        (**self).range()
469
0
    }
470
}
471
472
impl<'a, I> Range for &'a mut I
473
where
474
    I: Range + ?Sized,
475
{
476
24.7M
    fn len(&self) -> usize {
477
24.7M
        (**self).len()
478
24.7M
    }
<&mut &[u8] as combine::stream::Range>::len
Line
Count
Source
476
24.7M
    fn len(&self) -> usize {
477
24.7M
        (**self).len()
478
24.7M
    }
Unexecuted instantiation: <&mut _ as combine::stream::Range>::len
479
}
480
481
impl<'a> StreamOnce for &'a str {
482
    type Token = char;
483
    type Range = &'a str;
484
    type Position = PointerOffset<str>;
485
    type Error = StringStreamError;
486
487
    #[inline]
488
0
    fn uncons(&mut self) -> Result<char, StreamErrorFor<Self>> {
489
0
        let mut chars = self.chars();
490
0
        match chars.next() {
491
0
            Some(c) => {
492
0
                *self = chars.as_str();
493
0
                Ok(c)
494
            }
495
0
            None => Err(StringStreamError::Eoi),
496
        }
497
0
    }
498
}
499
500
impl<'a> Positioned for &'a str {
501
    #[inline]
502
0
    fn position(&self) -> Self::Position {
503
0
        PointerOffset::new(self.as_bytes().position().0)
504
0
    }
505
}
506
507
#[allow(clippy::while_let_loop)]
508
0
fn str_uncons_while<'a, F>(slice: &mut &'a str, mut chars: Chars<'a>, mut f: F) -> &'a str
509
0
where
510
0
    F: FnMut(char) -> bool,
511
{
512
0
    let mut last_char_size = 0;
513
514
    macro_rules! test_next {
515
        () => {
516
            match chars.next() {
517
                Some(c) => {
518
                    if !f(c) {
519
                        last_char_size = c.len_utf8();
520
                        break;
521
                    }
522
                }
523
                None => break,
524
            }
525
        };
526
    }
527
    loop {
528
0
        test_next!();
529
0
        test_next!();
530
0
        test_next!();
531
0
        test_next!();
532
0
        test_next!();
533
0
        test_next!();
534
0
        test_next!();
535
0
        test_next!();
536
    }
537
538
0
    let len = slice.len() - chars.as_str().len() - last_char_size;
539
0
    let (result, rest) = slice.split_at(len);
540
0
    *slice = rest;
541
0
    result
542
0
}
543
544
impl<'a> RangeStreamOnce for &'a str {
545
0
    fn uncons_while<F>(&mut self, f: F) -> Result<&'a str, StreamErrorFor<Self>>
546
0
    where
547
0
        F: FnMut(Self::Token) -> bool,
548
    {
549
0
        Ok(str_uncons_while(self, self.chars(), f))
550
0
    }
551
552
    #[inline]
553
0
    fn uncons_while1<F>(&mut self, mut f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>>
554
0
    where
555
0
        F: FnMut(Self::Token) -> bool,
556
    {
557
0
        let mut chars = self.chars();
558
0
        match chars.next() {
559
0
            Some(c) => {
560
0
                if !f(c) {
561
0
                    return PeekErr(Tracked::from(StringStreamError::UnexpectedParse));
562
0
                }
563
            }
564
0
            None => return PeekErr(Tracked::from(StringStreamError::Eoi)),
565
        }
566
567
0
        CommitOk(str_uncons_while(self, chars, f))
568
0
    }
569
570
    #[inline]
571
0
    fn uncons_range(&mut self, size: usize) -> Result<&'a str, StreamErrorFor<Self>> {
572
0
        fn is_char_boundary(s: &str, index: usize) -> bool {
573
0
            if index == s.len() {
574
0
                return true;
575
0
            }
576
0
            match s.as_bytes().get(index) {
577
0
                None => false,
578
0
                Some(b) => !(128..=192).contains(b),
579
            }
580
0
        }
581
0
        if size <= self.len() {
582
0
            if is_char_boundary(self, size) {
583
0
                let (result, remaining) = self.split_at(size);
584
0
                *self = remaining;
585
0
                Ok(result)
586
            } else {
587
0
                Err(StringStreamError::CharacterBoundary)
588
            }
589
        } else {
590
0
            Err(StringStreamError::Eoi)
591
        }
592
0
    }
593
594
    #[inline]
595
0
    fn distance(&self, end: &Self) -> usize {
596
0
        self.position().0 - end.position().0
597
0
    }
598
599
0
    fn range(&self) -> Self::Range {
600
0
        self
601
0
    }
602
}
603
604
impl<'a> Range for &'a str {
605
    #[inline]
606
0
    fn len(&self) -> usize {
607
0
        str::len(self)
608
0
    }
609
}
610
611
impl<'a, T> Range for &'a [T] {
612
    #[inline]
613
41.3M
    fn len(&self) -> usize {
614
41.3M
        <[T]>::len(self)
615
41.3M
    }
<&[u8] as combine::stream::Range>::len
Line
Count
Source
613
41.3M
    fn len(&self) -> usize {
614
41.3M
        <[T]>::len(self)
615
41.3M
    }
Unexecuted instantiation: <&[_] as combine::stream::Range>::len
616
}
617
618
#[repr(usize)]
619
enum UnconsStart {
620
    Zero = 0,
621
    One = 1,
622
}
623
624
0
fn slice_uncons_while<'a, T, F>(slice: &mut &'a [T], start: UnconsStart, mut f: F) -> &'a [T]
625
0
where
626
0
    F: FnMut(T) -> bool,
627
0
    T: Clone,
628
{
629
0
    let mut i = start as usize;
630
0
    let len = slice.len();
631
    // SAFETY: We only call this function with `One` if the slice has length >= 1
632
0
    debug_assert!(len >= i, "");
633
0
    let mut found = false;
634
635
    macro_rules! check {
636
        () => {
637
            if !f(unsafe { slice.get_unchecked(i).clone() }) {
638
                found = true;
639
                break;
640
            }
641
            i += 1;
642
        };
643
    }
644
645
    // SAFETY: ensures we can access at least 8 elements starting at i, making get_unchecked sound.
646
0
    while len - i >= 8 {
647
0
        check!();
648
0
        check!();
649
0
        check!();
650
0
        check!();
651
0
        check!();
652
0
        check!();
653
0
        check!();
654
0
        check!();
655
    }
656
657
0
    if !found {
658
0
        while let Some(c) = slice.get(i) {
659
0
            if !f(c.clone()) {
660
0
                break;
661
0
            }
662
0
            i += 1;
663
        }
664
0
    }
665
666
0
    let (result, remaining) = slice.split_at(i);
667
0
    *slice = remaining;
668
0
    result
669
0
}
670
671
impl<'a, T> RangeStreamOnce for &'a [T]
672
where
673
    T: Clone + PartialEq,
674
{
675
    #[inline]
676
24.7M
    fn uncons_range(&mut self, size: usize) -> Result<&'a [T], StreamErrorFor<Self>> {
677
24.7M
        if size <= self.len() {
678
24.7M
            let (result, remaining) = self.split_at(size);
679
24.7M
            *self = remaining;
680
24.7M
            Ok(result)
681
        } else {
682
4.79k
            Err(UnexpectedParse::Eoi)
683
        }
684
24.7M
    }
<&[u8] as combine::stream::RangeStreamOnce>::uncons_range
Line
Count
Source
676
24.7M
    fn uncons_range(&mut self, size: usize) -> Result<&'a [T], StreamErrorFor<Self>> {
677
24.7M
        if size <= self.len() {
678
24.7M
            let (result, remaining) = self.split_at(size);
679
24.7M
            *self = remaining;
680
24.7M
            Ok(result)
681
        } else {
682
4.79k
            Err(UnexpectedParse::Eoi)
683
        }
684
24.7M
    }
Unexecuted instantiation: <&[_] as combine::stream::RangeStreamOnce>::uncons_range
685
686
    #[inline]
687
0
    fn uncons_while<F>(&mut self, f: F) -> Result<&'a [T], StreamErrorFor<Self>>
688
0
    where
689
0
        F: FnMut(Self::Token) -> bool,
690
    {
691
0
        Ok(slice_uncons_while(self, UnconsStart::Zero, f))
692
0
    }
693
694
    #[inline]
695
0
    fn uncons_while1<F>(&mut self, mut f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>>
696
0
    where
697
0
        F: FnMut(Self::Token) -> bool,
698
    {
699
0
        match self.first() {
700
0
            Some(c) => {
701
0
                if !f(c.clone()) {
702
0
                    return PeekErr(Tracked::from(UnexpectedParse::Unexpected));
703
0
                }
704
            }
705
            None => {
706
0
                return PeekErr(Tracked::from(UnexpectedParse::Eoi));
707
            }
708
        }
709
710
0
        CommitOk(slice_uncons_while(self, UnconsStart::One, f))
711
0
    }
712
713
    #[inline]
714
8.25M
    fn distance(&self, end: &Self) -> usize {
715
8.25M
        end.len() - self.len()
716
8.25M
    }
<&[u8] as combine::stream::RangeStreamOnce>::distance
Line
Count
Source
714
8.25M
    fn distance(&self, end: &Self) -> usize {
715
8.25M
        end.len() - self.len()
716
8.25M
    }
Unexecuted instantiation: <&[_] as combine::stream::RangeStreamOnce>::distance
717
718
8.24M
    fn range(&self) -> Self::Range {
719
8.24M
        self
720
8.24M
    }
<&[u8] as combine::stream::RangeStreamOnce>::range
Line
Count
Source
718
8.24M
    fn range(&self) -> Self::Range {
719
8.24M
        self
720
8.24M
    }
Unexecuted instantiation: <&[_] as combine::stream::RangeStreamOnce>::range
721
}
722
723
impl<'a, T> Positioned for &'a [T]
724
where
725
    T: Clone + PartialEq,
726
{
727
    #[inline]
728
9.74M
    fn position(&self) -> Self::Position {
729
9.74M
        PointerOffset::new(self.as_ptr() as usize)
730
9.74M
    }
<&[u8] as combine::stream::Positioned>::position
Line
Count
Source
728
9.74M
    fn position(&self) -> Self::Position {
729
9.74M
        PointerOffset::new(self.as_ptr() as usize)
730
9.74M
    }
Unexecuted instantiation: <&[_] as combine::stream::Positioned>::position
731
}
732
733
impl<'a, T> StreamOnce for &'a [T]
734
where
735
    T: Clone + PartialEq,
736
{
737
    type Token = T;
738
    type Range = &'a [T];
739
    type Position = PointerOffset<[T]>;
740
    type Error = UnexpectedParse;
741
742
    #[inline]
743
8.50M
    fn uncons(&mut self) -> Result<T, StreamErrorFor<Self>> {
744
8.50M
        match self.split_first() {
745
8.49M
            Some((first, rest)) => {
746
8.49M
                *self = rest;
747
8.49M
                Ok(first.clone())
748
            }
749
15.6k
            None => Err(UnexpectedParse::Eoi),
750
        }
751
8.50M
    }
<&[u8] as combine::stream::StreamOnce>::uncons
Line
Count
Source
743
8.50M
    fn uncons(&mut self) -> Result<T, StreamErrorFor<Self>> {
744
8.50M
        match self.split_first() {
745
8.49M
            Some((first, rest)) => {
746
8.49M
                *self = rest;
747
8.49M
                Ok(first.clone())
748
            }
749
15.6k
            None => Err(UnexpectedParse::Eoi),
750
        }
751
8.50M
    }
Unexecuted instantiation: <&[_] as combine::stream::StreamOnce>::uncons
752
}
753
754
/// Stream type which indicates that the stream is partial if end of input is reached
755
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
756
pub struct PartialStream<S>(pub S);
757
758
impl<S> From<S> for PartialStream<S> {
759
0
    fn from(t: S) -> Self {
760
0
        PartialStream(t)
761
0
    }
762
}
763
764
impl<S> Positioned for PartialStream<S>
765
where
766
    S: Positioned,
767
{
768
    #[inline]
769
0
    fn position(&self) -> Self::Position {
770
0
        self.0.position()
771
0
    }
772
}
773
774
impl<S> ResetStream for PartialStream<S>
775
where
776
    S: ResetStream,
777
{
778
    type Checkpoint = S::Checkpoint;
779
780
    #[inline]
781
0
    fn checkpoint(&self) -> Self::Checkpoint {
782
0
        self.0.checkpoint()
783
0
    }
784
785
    #[inline]
786
0
    fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), S::Error> {
787
0
        self.0.reset(checkpoint)
788
0
    }
789
}
790
791
impl<S> StreamOnce for PartialStream<S>
792
where
793
    S: StreamOnce,
794
{
795
    type Token = S::Token;
796
    type Range = S::Range;
797
    type Position = S::Position;
798
    type Error = S::Error;
799
800
    #[inline]
801
0
    fn uncons(&mut self) -> Result<S::Token, StreamErrorFor<Self>> {
802
0
        self.0.uncons()
803
0
    }
804
805
0
    fn is_partial(&self) -> bool {
806
0
        true
807
0
    }
808
}
809
810
impl<S> RangeStreamOnce for PartialStream<S>
811
where
812
    S: RangeStreamOnce,
813
{
814
    #[inline]
815
0
    fn uncons_range(&mut self, size: usize) -> Result<Self::Range, StreamErrorFor<Self>> {
816
0
        self.0.uncons_range(size)
817
0
    }
818
819
    #[inline]
820
0
    fn uncons_while<F>(&mut self, f: F) -> Result<Self::Range, StreamErrorFor<Self>>
821
0
    where
822
0
        F: FnMut(Self::Token) -> bool,
823
    {
824
0
        self.0.uncons_while(f)
825
0
    }
826
827
0
    fn uncons_while1<F>(&mut self, f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>>
828
0
    where
829
0
        F: FnMut(Self::Token) -> bool,
830
    {
831
0
        self.0.uncons_while1(f)
832
0
    }
833
834
    #[inline]
835
0
    fn distance(&self, end: &Self::Checkpoint) -> usize {
836
0
        self.0.distance(end)
837
0
    }
838
839
    #[inline]
840
0
    fn range(&self) -> Self::Range {
841
0
        self.0.range()
842
0
    }
843
}
844
845
/// Stream type which indicates that the stream is complete if end of input is reached
846
///
847
/// For most streams this is already the default but this wrapper can be used to override a nested
848
/// `PartialStream`
849
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
850
#[repr(transparent)]
851
pub struct CompleteStream<S>(pub S);
852
853
impl<S> From<S> for CompleteStream<S> {
854
0
    fn from(t: S) -> Self {
855
0
        CompleteStream(t)
856
0
    }
857
}
858
859
impl<'s, S> From<&'s mut S> for &'s mut CompleteStream<S> {
860
0
    fn from(t: &'s mut S) -> Self {
861
        // SAFETY repr(transparent) is specified on CompleteStream
862
0
        unsafe { &mut *(t as *mut S as *mut CompleteStream<S>) }
863
0
    }
864
}
865
866
impl<S> Positioned for CompleteStream<S>
867
where
868
    S: Positioned,
869
{
870
    #[inline]
871
0
    fn position(&self) -> Self::Position {
872
0
        self.0.position()
873
0
    }
874
}
875
876
impl<S> ResetStream for CompleteStream<S>
877
where
878
    S: ResetStream,
879
{
880
    type Checkpoint = S::Checkpoint;
881
882
    #[inline]
883
0
    fn checkpoint(&self) -> Self::Checkpoint {
884
0
        self.0.checkpoint()
885
0
    }
886
887
    #[inline]
888
0
    fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), S::Error> {
889
0
        self.0.reset(checkpoint)
890
0
    }
891
}
892
893
impl<S> StreamOnce for CompleteStream<S>
894
where
895
    S: StreamOnce,
896
{
897
    type Token = S::Token;
898
    type Range = S::Range;
899
    type Position = S::Position;
900
    type Error = S::Error;
901
902
    #[inline]
903
0
    fn uncons(&mut self) -> Result<S::Token, StreamErrorFor<Self>> {
904
0
        self.0.uncons()
905
0
    }
906
907
0
    fn is_partial(&self) -> bool {
908
0
        false
909
0
    }
910
}
911
912
impl<S> RangeStreamOnce for CompleteStream<S>
913
where
914
    S: RangeStreamOnce,
915
{
916
    #[inline]
917
0
    fn uncons_range(&mut self, size: usize) -> Result<Self::Range, StreamErrorFor<Self>> {
918
0
        self.0.uncons_range(size)
919
0
    }
920
921
    #[inline]
922
0
    fn uncons_while<F>(&mut self, f: F) -> Result<Self::Range, StreamErrorFor<Self>>
923
0
    where
924
0
        F: FnMut(Self::Token) -> bool,
925
    {
926
0
        self.0.uncons_while(f)
927
0
    }
928
929
0
    fn uncons_while1<F>(&mut self, f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>>
930
0
    where
931
0
        F: FnMut(Self::Token) -> bool,
932
    {
933
0
        self.0.uncons_while1(f)
934
0
    }
935
936
    #[inline]
937
0
    fn distance(&self, end: &Self::Checkpoint) -> usize {
938
0
        self.0.distance(end)
939
0
    }
940
941
    #[inline]
942
0
    fn range(&self) -> Self::Range {
943
0
        self.0.range()
944
0
    }
945
}
946
947
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
948
pub struct MaybePartialStream<S>(pub S, pub bool);
949
950
impl<S> Positioned for MaybePartialStream<S>
951
where
952
    S: Positioned,
953
{
954
    #[inline]
955
9.74M
    fn position(&self) -> Self::Position {
956
9.74M
        self.0.position()
957
9.74M
    }
<combine::stream::MaybePartialStream<&[u8]> as combine::stream::Positioned>::position
Line
Count
Source
955
9.74M
    fn position(&self) -> Self::Position {
956
9.74M
        self.0.position()
957
9.74M
    }
Unexecuted instantiation: <combine::stream::MaybePartialStream<_> as combine::stream::Positioned>::position
958
}
959
960
impl<S> ResetStream for MaybePartialStream<S>
961
where
962
    S: ResetStream,
963
{
964
    type Checkpoint = S::Checkpoint;
965
966
    #[inline]
967
60.4M
    fn checkpoint(&self) -> Self::Checkpoint {
968
60.4M
        self.0.checkpoint()
969
60.4M
    }
<combine::stream::MaybePartialStream<&[u8]> as combine::stream::ResetStream>::checkpoint
Line
Count
Source
967
60.4M
    fn checkpoint(&self) -> Self::Checkpoint {
968
60.4M
        self.0.checkpoint()
969
60.4M
    }
Unexecuted instantiation: <combine::stream::MaybePartialStream<_> as combine::stream::ResetStream>::checkpoint
970
971
    #[inline]
972
16.4M
    fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), S::Error> {
973
16.4M
        self.0.reset(checkpoint)
974
16.4M
    }
<combine::stream::MaybePartialStream<&[u8]> as combine::stream::ResetStream>::reset
Line
Count
Source
972
16.4M
    fn reset(&mut self, checkpoint: Self::Checkpoint) -> Result<(), S::Error> {
973
16.4M
        self.0.reset(checkpoint)
974
16.4M
    }
Unexecuted instantiation: <combine::stream::MaybePartialStream<_> as combine::stream::ResetStream>::reset
975
}
976
977
impl<S> StreamOnce for MaybePartialStream<S>
978
where
979
    S: StreamOnce,
980
{
981
    type Token = S::Token;
982
    type Range = S::Range;
983
    type Position = S::Position;
984
    type Error = S::Error;
985
986
    #[inline]
987
8.50M
    fn uncons(&mut self) -> Result<S::Token, StreamErrorFor<Self>> {
988
8.50M
        self.0.uncons()
989
8.50M
    }
<combine::stream::MaybePartialStream<&[u8]> as combine::stream::StreamOnce>::uncons
Line
Count
Source
987
8.50M
    fn uncons(&mut self) -> Result<S::Token, StreamErrorFor<Self>> {
988
8.50M
        self.0.uncons()
989
8.50M
    }
Unexecuted instantiation: <combine::stream::MaybePartialStream<_> as combine::stream::StreamOnce>::uncons
990
991
258k
    fn is_partial(&self) -> bool {
992
258k
        self.1
993
258k
    }
<combine::stream::MaybePartialStream<&[u8]> as combine::stream::StreamOnce>::is_partial
Line
Count
Source
991
258k
    fn is_partial(&self) -> bool {
992
258k
        self.1
993
258k
    }
Unexecuted instantiation: <combine::stream::MaybePartialStream<_> as combine::stream::StreamOnce>::is_partial
994
}
995
996
impl<S> RangeStreamOnce for MaybePartialStream<S>
997
where
998
    S: RangeStreamOnce,
999
{
1000
    #[inline]
1001
24.7M
    fn uncons_range(&mut self, size: usize) -> Result<Self::Range, StreamErrorFor<Self>> {
1002
24.7M
        self.0.uncons_range(size)
1003
24.7M
    }
<combine::stream::MaybePartialStream<&[u8]> as combine::stream::RangeStreamOnce>::uncons_range
Line
Count
Source
1001
24.7M
    fn uncons_range(&mut self, size: usize) -> Result<Self::Range, StreamErrorFor<Self>> {
1002
24.7M
        self.0.uncons_range(size)
1003
24.7M
    }
Unexecuted instantiation: <combine::stream::MaybePartialStream<_> as combine::stream::RangeStreamOnce>::uncons_range
1004
1005
    #[inline]
1006
0
    fn uncons_while<F>(&mut self, f: F) -> Result<Self::Range, StreamErrorFor<Self>>
1007
0
    where
1008
0
        F: FnMut(Self::Token) -> bool,
1009
    {
1010
0
        self.0.uncons_while(f)
1011
0
    }
1012
1013
0
    fn uncons_while1<F>(&mut self, f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>>
1014
0
    where
1015
0
        F: FnMut(Self::Token) -> bool,
1016
    {
1017
0
        self.0.uncons_while1(f)
1018
0
    }
1019
1020
    #[inline]
1021
8.25M
    fn distance(&self, end: &Self::Checkpoint) -> usize {
1022
8.25M
        self.0.distance(end)
1023
8.25M
    }
<combine::stream::MaybePartialStream<&[u8]> as combine::stream::RangeStreamOnce>::distance
Line
Count
Source
1021
8.25M
    fn distance(&self, end: &Self::Checkpoint) -> usize {
1022
8.25M
        self.0.distance(end)
1023
8.25M
    }
Unexecuted instantiation: <combine::stream::MaybePartialStream<_> as combine::stream::RangeStreamOnce>::distance
1024
1025
    #[inline]
1026
8.24M
    fn range(&self) -> Self::Range {
1027
8.24M
        self.0.range()
1028
8.24M
    }
<combine::stream::MaybePartialStream<&[u8]> as combine::stream::RangeStreamOnce>::range
Line
Count
Source
1026
8.24M
    fn range(&self) -> Self::Range {
1027
8.24M
        self.0.range()
1028
8.24M
    }
Unexecuted instantiation: <combine::stream::MaybePartialStream<_> as combine::stream::RangeStreamOnce>::range
1029
}
1030
1031
/// Newtype for constructing a stream from a slice where the items in the slice are not copyable.
1032
#[derive(Copy, Eq, PartialEq, Ord, PartialOrd, Debug)]
1033
pub struct SliceStream<'a, T>(pub &'a [T]);
1034
1035
impl<'a, T> Clone for SliceStream<'a, T> {
1036
0
    fn clone(&self) -> SliceStream<'a, T> {
1037
0
        SliceStream(self.0)
1038
0
    }
1039
}
1040
1041
impl<'a, T> Positioned for SliceStream<'a, T>
1042
where
1043
    T: PartialEq + 'a,
1044
{
1045
    #[inline]
1046
0
    fn position(&self) -> Self::Position {
1047
0
        PointerOffset::new(self.0.as_ptr() as usize)
1048
0
    }
1049
}
1050
1051
impl<'a, T> StreamOnce for SliceStream<'a, T>
1052
where
1053
    T: PartialEq + 'a,
1054
{
1055
    type Token = &'a T;
1056
    type Range = &'a [T];
1057
    type Position = PointerOffset<[T]>;
1058
    type Error = UnexpectedParse;
1059
1060
    #[inline]
1061
0
    fn uncons(&mut self) -> Result<&'a T, StreamErrorFor<Self>> {
1062
0
        match self.0.split_first() {
1063
0
            Some((first, rest)) => {
1064
0
                self.0 = rest;
1065
0
                Ok(first)
1066
            }
1067
0
            None => Err(UnexpectedParse::Eoi),
1068
        }
1069
0
    }
1070
}
1071
1072
0
fn slice_uncons_while_ref<'a, T, F>(slice: &mut &'a [T], start: UnconsStart, mut f: F) -> &'a [T]
1073
0
where
1074
0
    F: FnMut(&'a T) -> bool,
1075
{
1076
0
    let mut i = start as usize;
1077
0
    let len = slice.len();
1078
    // SAFETY: We only call this function with `One` if the slice has length >= 1
1079
0
    debug_assert!(len >= i, "");
1080
0
    let mut found = false;
1081
1082
    macro_rules! check {
1083
        () => {
1084
            if !f(unsafe { slice.get_unchecked(i) }) {
1085
                found = true;
1086
                break;
1087
            }
1088
            i += 1;
1089
        };
1090
    }
1091
1092
    // SAFETY: ensures we can access at least 8 elements starting at i, making get_unchecked sound.
1093
0
    while len - i >= 8 {
1094
0
        check!();
1095
0
        check!();
1096
0
        check!();
1097
0
        check!();
1098
0
        check!();
1099
0
        check!();
1100
0
        check!();
1101
0
        check!();
1102
    }
1103
1104
0
    if !found {
1105
0
        while let Some(c) = slice.get(i) {
1106
0
            if !f(c) {
1107
0
                break;
1108
0
            }
1109
0
            i += 1;
1110
        }
1111
0
    }
1112
1113
0
    let (result, remaining) = slice.split_at(i);
1114
0
    *slice = remaining;
1115
0
    result
1116
0
}
1117
1118
impl<'a, T> RangeStreamOnce for SliceStream<'a, T>
1119
where
1120
    T: PartialEq + 'a,
1121
{
1122
    #[inline]
1123
0
    fn uncons_range(&mut self, size: usize) -> Result<&'a [T], StreamErrorFor<Self>> {
1124
0
        if size <= self.0.len() {
1125
0
            let (range, rest) = self.0.split_at(size);
1126
0
            self.0 = rest;
1127
0
            Ok(range)
1128
        } else {
1129
0
            Err(UnexpectedParse::Eoi)
1130
        }
1131
0
    }
1132
1133
    #[inline]
1134
0
    fn uncons_while<F>(&mut self, f: F) -> Result<&'a [T], StreamErrorFor<Self>>
1135
0
    where
1136
0
        F: FnMut(Self::Token) -> bool,
1137
    {
1138
0
        Ok(slice_uncons_while_ref(&mut self.0, UnconsStart::Zero, f))
1139
0
    }
1140
1141
    #[inline]
1142
0
    fn uncons_while1<F>(&mut self, mut f: F) -> ParseResult<Self::Range, StreamErrorFor<Self>>
1143
0
    where
1144
0
        F: FnMut(Self::Token) -> bool,
1145
    {
1146
0
        match self.0.first() {
1147
0
            Some(c) => {
1148
0
                if !f(c) {
1149
0
                    return PeekErr(Tracked::from(UnexpectedParse::Unexpected));
1150
0
                }
1151
            }
1152
0
            None => return PeekErr(Tracked::from(UnexpectedParse::Eoi)),
1153
        }
1154
1155
0
        CommitOk(slice_uncons_while_ref(&mut self.0, UnconsStart::One, f))
1156
0
    }
1157
1158
    #[inline]
1159
0
    fn distance(&self, end: &Self) -> usize {
1160
0
        end.0.len() - self.0.len()
1161
0
    }
1162
1163
0
    fn range(&self) -> Self::Range {
1164
0
        self.0
1165
0
    }
1166
}
1167
1168
/// Wrapper around iterators which allows them to be treated as a stream.
1169
/// Returned by [`IteratorStream::new`].
1170
#[derive(Copy, Clone, Debug)]
1171
pub struct IteratorStream<Input>(Input);
1172
1173
impl<Input> IteratorStream<Input>
1174
where
1175
    Input: Iterator,
1176
{
1177
    /// Converts an `Iterator` into a stream.
1178
    ///
1179
    /// NOTE: This type do not implement `Positioned` and `Clone` and must be wrapped with types
1180
    ///     such as `BufferedStreamRef` and `State` to become a `Stream` which can be parsed
1181
0
    pub fn new<T>(iter: T) -> IteratorStream<Input>
1182
0
    where
1183
0
        T: IntoIterator<IntoIter = Input, Item = Input::Item>,
1184
    {
1185
0
        IteratorStream(iter.into_iter())
1186
0
    }
1187
}
1188
1189
impl<Input> Iterator for IteratorStream<Input>
1190
where
1191
    Input: Iterator,
1192
{
1193
    type Item = Input::Item;
1194
0
    fn next(&mut self) -> Option<Input::Item> {
1195
0
        self.0.next()
1196
0
    }
1197
}
1198
1199
impl<Input: Iterator> StreamOnce for IteratorStream<Input>
1200
where
1201
    Input::Item: Clone + PartialEq,
1202
{
1203
    type Token = Input::Item;
1204
    type Range = Input::Item;
1205
    type Position = ();
1206
    type Error = UnexpectedParse;
1207
1208
    #[inline]
1209
0
    fn uncons(&mut self) -> Result<Self::Token, StreamErrorFor<Self>> {
1210
0
        match self.next() {
1211
0
            Some(x) => Ok(x),
1212
0
            None => Err(UnexpectedParse::Eoi),
1213
        }
1214
0
    }
1215
}
1216
1217
/// Newtype around a pointer offset into a slice stream (`&[T]`/`&str`).
1218
pub struct PointerOffset<T: ?Sized>(pub usize, PhantomData<T>);
1219
1220
impl<T: ?Sized> Clone for PointerOffset<T> {
1221
0
    fn clone(&self) -> Self {
1222
0
        PointerOffset::new(self.0)
1223
0
    }
Unexecuted instantiation: <combine::stream::PointerOffset<[u8]> as core::clone::Clone>::clone
Unexecuted instantiation: <combine::stream::PointerOffset<_> as core::clone::Clone>::clone
1224
}
1225
1226
impl<T: ?Sized> Copy for PointerOffset<T> {}
1227
1228
impl<T: ?Sized> Default for PointerOffset<T> {
1229
7.58k
    fn default() -> Self {
1230
7.58k
        PointerOffset::new(0)
1231
7.58k
    }
<combine::stream::PointerOffset<[u8]> as core::default::Default>::default
Line
Count
Source
1229
7.58k
    fn default() -> Self {
1230
7.58k
        PointerOffset::new(0)
1231
7.58k
    }
Unexecuted instantiation: <combine::stream::PointerOffset<_> as core::default::Default>::default
1232
}
1233
1234
impl<T: ?Sized> PartialEq for PointerOffset<T> {
1235
0
    fn eq(&self, other: &Self) -> bool {
1236
0
        self.0 == other.0
1237
0
    }
1238
}
1239
1240
impl<T: ?Sized> Eq for PointerOffset<T> {}
1241
1242
impl<T: ?Sized> PartialOrd for PointerOffset<T> {
1243
0
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1244
0
        self.0.partial_cmp(&other.0)
1245
0
    }
1246
}
1247
1248
impl<T: ?Sized> Ord for PointerOffset<T> {
1249
1.45k
    fn cmp(&self, other: &Self) -> Ordering {
1250
1.45k
        self.0.cmp(&other.0)
1251
1.45k
    }
<combine::stream::PointerOffset<[u8]> as core::cmp::Ord>::cmp
Line
Count
Source
1249
1.45k
    fn cmp(&self, other: &Self) -> Ordering {
1250
1.45k
        self.0.cmp(&other.0)
1251
1.45k
    }
Unexecuted instantiation: <combine::stream::PointerOffset<_> as core::cmp::Ord>::cmp
1252
}
1253
1254
impl<T> fmt::Debug for PointerOffset<T>
1255
where
1256
    T: ?Sized,
1257
{
1258
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1259
0
        write!(f, "{}", self)
1260
0
    }
1261
}
1262
1263
impl<T> fmt::Display for PointerOffset<T>
1264
where
1265
    T: ?Sized,
1266
{
1267
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1268
0
        write!(f, "PointerOffset({:?})", self.0 as *const ())
1269
0
    }
1270
}
1271
1272
impl<T> PointerOffset<T>
1273
where
1274
    T: ?Sized,
1275
{
1276
9.75M
    pub fn new(offset: usize) -> Self {
1277
9.75M
        PointerOffset(offset, PhantomData)
1278
9.75M
    }
<combine::stream::PointerOffset<[u8]>>::new
Line
Count
Source
1276
9.75M
    pub fn new(offset: usize) -> Self {
1277
9.75M
        PointerOffset(offset, PhantomData)
1278
9.75M
    }
Unexecuted instantiation: <combine::stream::PointerOffset<_>>::new
1279
1280
    /// Converts the pointer-based position into an indexed position.
1281
    ///
1282
    /// ```rust
1283
    /// # extern crate combine;
1284
    /// # use combine::*;
1285
    /// # fn main() {
1286
    /// let text = "b";
1287
    /// let err = token('a').easy_parse(text).unwrap_err();
1288
    /// assert_eq!(err.position.0, text.as_ptr() as usize);
1289
    /// assert_eq!(err.map_position(|p| p.translate_position(text)).position, 0);
1290
    /// # }
1291
    /// ```
1292
1.82k
    pub fn translate_position(mut self, initial_slice: &T) -> usize {
1293
1.82k
        self.0 -= initial_slice as *const T as *const () as usize;
1294
1.82k
        self.0
1295
1.82k
    }
<combine::stream::PointerOffset<[u8]>>::translate_position
Line
Count
Source
1292
1.82k
    pub fn translate_position(mut self, initial_slice: &T) -> usize {
1293
1.82k
        self.0 -= initial_slice as *const T as *const () as usize;
1294
1.82k
        self.0
1295
1.82k
    }
Unexecuted instantiation: <combine::stream::PointerOffset<_>>::translate_position
1296
}
1297
1298
/// Decodes `input` using `parser`.
1299
///
1300
/// Return `Ok(Some(token), committed_data)` if there was enough data to finish parsing using
1301
/// `parser`.
1302
/// Returns `Ok(None, committed_data)` if `input` did not contain enough data to finish parsing
1303
/// using `parser`.
1304
///
1305
/// See `examples/async.rs` for example usage in a `tokio_io::codec::Decoder`
1306
54.2k
pub fn decode<Input, P>(
1307
54.2k
    mut parser: P,
1308
54.2k
    input: &mut Input,
1309
54.2k
    partial_state: &mut P::PartialState,
1310
54.2k
) -> Result<(Option<P::Output>, usize), <Input as StreamOnce>::Error>
1311
54.2k
where
1312
54.2k
    P: Parser<Input>,
1313
54.2k
    Input: RangeStream,
1314
{
1315
54.2k
    let start = input.checkpoint();
1316
54.2k
    match parser.parse_with_state(input, partial_state) {
1317
2.15k
        Ok(message) => Ok((Some(message), input.distance(&start))),
1318
52.0k
        Err(err) => {
1319
52.0k
            if err.is_unexpected_end_of_input() {
1320
50.2k
                if input.is_partial() {
1321
                    // The parser expected more input to parse and input is partial, return `None`
1322
                    // as we did not finish and also return how much may be removed from the stream
1323
46.6k
                    Ok((None, input.distance(&start)))
1324
                } else {
1325
3.61k
                    Err(err)
1326
                }
1327
            } else {
1328
1.82k
                Err(err)
1329
            }
1330
        }
1331
    }
1332
54.2k
}
combine::stream::decode::<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, combine::parser::combinator::Opaque<redis::parser::value<combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>::{closure#0}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, redis::types::Value, combine::parser::combinator::AnySendSyncPartialState>>
Line
Count
Source
1306
54.2k
pub fn decode<Input, P>(
1307
54.2k
    mut parser: P,
1308
54.2k
    input: &mut Input,
1309
54.2k
    partial_state: &mut P::PartialState,
1310
54.2k
) -> Result<(Option<P::Output>, usize), <Input as StreamOnce>::Error>
1311
54.2k
where
1312
54.2k
    P: Parser<Input>,
1313
54.2k
    Input: RangeStream,
1314
{
1315
54.2k
    let start = input.checkpoint();
1316
54.2k
    match parser.parse_with_state(input, partial_state) {
1317
2.15k
        Ok(message) => Ok((Some(message), input.distance(&start))),
1318
52.0k
        Err(err) => {
1319
52.0k
            if err.is_unexpected_end_of_input() {
1320
50.2k
                if input.is_partial() {
1321
                    // The parser expected more input to parse and input is partial, return `None`
1322
                    // as we did not finish and also return how much may be removed from the stream
1323
46.6k
                    Ok((None, input.distance(&start)))
1324
                } else {
1325
3.61k
                    Err(err)
1326
                }
1327
            } else {
1328
1.82k
                Err(err)
1329
            }
1330
        }
1331
    }
1332
54.2k
}
Unexecuted instantiation: combine::stream::decode::<_, _>
1333
1334
/// Decodes `input` using `parser`. Like `decode` but works directly in both
1335
/// `tokio_util::Decoder::decode` and `tokio_util::Decoder::decode_eof`
1336
///
1337
/// Return `Ok(Some(token), committed_data)` if there was enough data to finish parsing using
1338
/// `parser`.
1339
/// Returns `Ok(None, committed_data)` if `input` did not contain enough data to finish parsing
1340
/// using `parser`.
1341
/// Returns `Ok(None, 0)` if `input` did not contain enough data to finish parsing
1342
/// using `parser`.
1343
///
1344
/// See `examples/async.rs` for example usage in a `tokio_io::codec::Decoder`
1345
0
pub fn decode_tokio<Input, P>(
1346
0
    mut parser: P,
1347
0
    input: &mut Input,
1348
0
    partial_state: &mut P::PartialState,
1349
0
) -> Result<(Option<P::Output>, usize), <Input as StreamOnce>::Error>
1350
0
where
1351
0
    P: Parser<Input>,
1352
0
    Input: RangeStream,
1353
{
1354
0
    let start = input.checkpoint();
1355
0
    match parser.parse_with_state(input, partial_state) {
1356
0
        Ok(message) => Ok((Some(message), input.distance(&start))),
1357
0
        Err(err) => {
1358
0
            if err.is_unexpected_end_of_input() {
1359
0
                if input.is_partial() {
1360
                    // The parser expected more input to parse and input is partial, return `None`
1361
                    // as we did not finish and also return how much may be removed from the stream
1362
0
                    Ok((None, input.distance(&start)))
1363
0
                } else if input_at_eof(input) && input.distance(&start) == 0 {
1364
                    // We are at eof and the input is empty, return None to indicate that we are
1365
                    // done
1366
0
                    Ok((None, 0))
1367
                } else {
1368
0
                    Err(err)
1369
                }
1370
            } else {
1371
0
                Err(err)
1372
            }
1373
        }
1374
    }
1375
0
}
1376
1377
/// Parses an instance of `std::io::Read` as a `&[u8]` without reading the entire file into
1378
/// memory.
1379
///
1380
/// This is defined as a macro to work around the lack of Higher Ranked Types. See the
1381
/// example for how to pass a parser to the macro (constructing parts of the parser outside of
1382
/// the `decode!` call is unlikely to work.
1383
///
1384
/// ```
1385
/// use std::{
1386
///     fs::File,
1387
/// };
1388
/// use combine::{decode, satisfy, skip_many1, many1, sep_end_by, Parser, stream::Decoder};
1389
///
1390
/// let mut read = File::open("README.md").unwrap();
1391
/// let mut decoder = Decoder::new();
1392
/// let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
1393
/// assert_eq!(
1394
///     decode!(
1395
///         decoder,
1396
///         read,
1397
///         {
1398
///             let word = many1(satisfy(|b| !is_whitespace(b)));
1399
///             sep_end_by(word, skip_many1(satisfy(is_whitespace))).map(|words: Vec<Vec<u8>>| words.len())
1400
///         },
1401
///         |input, _position| combine::easy::Stream::from(input),
1402
///     ).map_err(combine::easy::Errors::<u8, &[u8], _>::from),
1403
///     Ok(773),
1404
/// );
1405
/// ```
1406
#[cfg(feature = "std")]
1407
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1408
#[macro_export]
1409
macro_rules! decode {
1410
    ($decoder: expr, $read: expr, $parser: expr $(,)?) => {
1411
        $crate::decode!($decoder, $read, $parser, |input, _position| input, |x| x)
1412
    };
1413
1414
    ($decoder: expr, $read: expr, $parser: expr, $input_stream: expr $(,)?) => {
1415
        $crate::decode!($decoder, $read, $parser, $input_stream, |x| x)
1416
    };
1417
1418
    ($decoder: expr, $read: expr, $parser: expr, $input_stream: expr, $post_decode: expr $(,)?) => {
1419
        match $decoder {
1420
            ref mut decoder => match $read {
1421
                ref mut read => 'outer: loop {
1422
                    let (opt, removed) = {
1423
                        let (state, position, buffer, end_of_input) = decoder.__inner();
1424
                        let buffer =
1425
                            $crate::stream::buf_reader::CombineBuffer::buffer(buffer, read);
1426
1427
                        let mut stream = $crate::stream::call_with2(
1428
                            $crate::stream::MaybePartialStream(buffer, !end_of_input),
1429
                            *position,
1430
                            $input_stream,
1431
                        );
1432
                        let result = $crate::stream::decode($parser, &mut stream, state);
1433
                        *position = $crate::stream::Positioned::position(&stream);
1434
                        $crate::stream::call_with(stream, $post_decode);
1435
                        match result {
1436
                            Ok(x) => x,
1437
                            Err(err) => {
1438
                                break 'outer Err($crate::stream::decoder::Error::Parse(err))
1439
                            }
1440
                        }
1441
                    };
1442
1443
                    decoder.advance(&mut *read, removed);
1444
1445
                    if let Some(v) = opt {
1446
                        break 'outer Ok(v);
1447
                    }
1448
1449
                    match decoder.__before_parse(&mut *read) {
1450
                        Ok(x) => x,
1451
                        Err(error) => {
1452
                            break 'outer Err($crate::stream::decoder::Error::Io {
1453
                                error,
1454
                                position: Clone::clone(decoder.position()),
1455
                            })
1456
                        }
1457
                    };
1458
                },
1459
            },
1460
        }
1461
    };
1462
}
1463
1464
/// Parses an instance of `futures::io::AsyncRead` as a `&[u8]` without reading the entire file into
1465
/// memory.
1466
///
1467
/// This is defined as a macro to work around the lack of Higher Ranked Types. See the
1468
/// example for how to pass a parser to the macro (constructing parts of the parser outside of
1469
/// the `decode!` call is unlikely to work.
1470
///
1471
/// ```
1472
/// # use futures_03_dep as futures;
1473
/// use futures::pin_mut;
1474
/// use async_std::{
1475
///     fs::File,
1476
///     task,
1477
/// };
1478
///
1479
/// use combine::{decode_futures_03, satisfy, skip_many1, many1, sep_end_by, Parser, stream::Decoder};
1480
///
1481
/// fn main() {
1482
///     task::block_on(main_());
1483
/// }
1484
///
1485
/// async fn main_() {
1486
///     let mut read = File::open("README.md").await.unwrap();
1487
///     let mut decoder = Decoder::new();
1488
///     let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
1489
///     assert_eq!(
1490
///         decode_futures_03!(
1491
///             decoder,
1492
///             read,
1493
///             {
1494
///                 let word = many1(satisfy(|b| !is_whitespace(b)));
1495
///                 sep_end_by(word, skip_many1(satisfy(is_whitespace))).map(|words: Vec<Vec<u8>>| words.len())
1496
///             },
1497
///             |input, _position| combine::easy::Stream::from(input),
1498
///         ).map_err(combine::easy::Errors::<u8, &[u8], _>::from),
1499
///         Ok(773),
1500
///     );
1501
/// }
1502
/// ```
1503
#[cfg(feature = "futures-io-03")]
1504
#[cfg_attr(docsrs, doc(cfg(feature = "futures-io-03")))]
1505
#[macro_export]
1506
macro_rules! decode_futures_03 {
1507
    ($decoder: expr, $read: expr, $parser: expr) => {
1508
        $crate::decode_futures_03!($decoder, $read, $parser, |x| x $(,)?)
1509
    };
1510
1511
1512
    ($decoder: expr, $read: expr, $parser: expr, $input_stream: expr $(,)?) => {
1513
        $crate::decode_futures_03!($decoder, $read, $parser, $input_stream, |x| x)
1514
    };
1515
1516
    ($decoder: expr, $read: expr, $parser: expr, $input_stream: expr, $post_decode: expr $(,)?) => {
1517
        match $decoder {
1518
            ref mut decoder => match $read {
1519
                ref mut read => 'outer: loop {
1520
                    let (opt, removed) = {
1521
                        let (state, position, buffer, end_of_input) = decoder.__inner();
1522
                        let buffer =
1523
                            $crate::stream::buf_reader::CombineBuffer::buffer(buffer, &*read);
1524
1525
                        let mut stream = $crate::stream::call_with2(
1526
                            $crate::stream::MaybePartialStream(buffer, !end_of_input),
1527
                            *position,
1528
                            $input_stream,
1529
                        );
1530
                        let result = $crate::stream::decode($parser, &mut stream, state);
1531
                        *position = $crate::stream::Positioned::position(&stream);
1532
                        $crate::stream::call_with(stream, $post_decode);
1533
                        match result {
1534
                            Ok(x) => x,
1535
                            Err(err) => break 'outer Err($crate::stream::decoder::Error::Parse(err)),
1536
                        }
1537
                    };
1538
1539
                    decoder.advance_pin(std::pin::Pin::new(&mut *read), removed);
1540
1541
                    if let Some(v) = opt {
1542
                        break 'outer Ok(v);
1543
                    }
1544
1545
1546
                    match decoder.__before_parse_async(std::pin::Pin::new(&mut *read)).await {
1547
                        Ok(_) => (),
1548
                        Err(error) => {
1549
                            break 'outer Err($crate::stream::decoder::Error::Io {
1550
                                error,
1551
                                position: Clone::clone(decoder.position()),
1552
                            })
1553
                        }
1554
                    };
1555
                }
1556
            }
1557
        }
1558
    };
1559
}
1560
1561
/// Parses an instance of `tokio::io::AsyncRead` as a `&[u8]` without reading the entire file into
1562
/// memory.
1563
///
1564
/// This is defined as a macro to work around the lack of Higher Ranked Types. See the
1565
/// example for how to pass a parser to the macro (constructing parts of the parser outside of
1566
/// the `decode!` call is unlikely to work.
1567
///
1568
/// ```
1569
/// # use tokio_02_dep as tokio;
1570
/// # use futures_03_dep as futures;
1571
/// use futures::pin_mut;
1572
/// use tokio::{
1573
///     fs::File,
1574
/// };
1575
///
1576
/// use combine::{decode_tokio_02, satisfy, skip_many1, many1, sep_end_by, Parser, stream::{Decoder, buf_reader::BufReader}};
1577
///
1578
/// #[tokio::main]
1579
/// async fn main() {
1580
///     let mut read = BufReader::new(File::open("README.md").await.unwrap());
1581
///     let mut decoder = Decoder::new_bufferless();
1582
///     let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
1583
///     assert_eq!(
1584
///         decode_tokio_02!(
1585
///             decoder,
1586
///             read,
1587
///             {
1588
///                 let word = many1(satisfy(|b| !is_whitespace(b)));
1589
///                 sep_end_by(word, skip_many1(satisfy(is_whitespace))).map(|words: Vec<Vec<u8>>| words.len())
1590
///             },
1591
///             |input, _position| combine::easy::Stream::from(input),
1592
///         ).map_err(combine::easy::Errors::<u8, &[u8], _>::from),
1593
///         Ok(773),
1594
///     );
1595
/// }
1596
/// ```
1597
#[cfg(feature = "tokio-02")]
1598
#[cfg_attr(docsrs, doc(cfg(feature = "tokio-02")))]
1599
#[macro_export]
1600
macro_rules! decode_tokio_02 {
1601
    ($decoder: expr, $read: expr, $parser: expr $(,)?) => {
1602
        $crate::decode_tokio_02!($decoder, $read, $parser, |input, _position| input)
1603
    };
1604
1605
    ($decoder: expr, $read: expr, $parser: expr, $input_stream: expr $(,)?) => {
1606
        $crate::decode_tokio_02!($decoder, $read, $parser, $input_stream, |x| x)
1607
    };
1608
1609
    ($decoder: expr, $read: expr, $parser: expr, $input_stream: expr, $post_decode: expr $(,)?) => {
1610
        match $decoder {
1611
            ref mut decoder => match $read {
1612
                ref mut read => 'outer: loop {
1613
                    let (opt, removed) = {
1614
                        let (state, position, buffer, end_of_input) = decoder.__inner();
1615
                        let buffer =
1616
                            $crate::stream::buf_reader::CombineBuffer::buffer(buffer, &*read);
1617
                        let mut stream = $crate::stream::call_with2(
1618
                            $crate::stream::MaybePartialStream(buffer, !end_of_input),
1619
                            *position,
1620
                            $input_stream,
1621
                        );
1622
                        let result = $crate::stream::decode($parser, &mut stream, state);
1623
                        *position = $crate::stream::Positioned::position(&stream);
1624
                        $crate::stream::call_with(stream, $post_decode);
1625
                        match result {
1626
                            Ok(x) => x,
1627
                            Err(err) => {
1628
                                break 'outer Err($crate::stream::decoder::Error::Parse(err))
1629
                            }
1630
                        }
1631
                    };
1632
1633
                    decoder.advance_pin(std::pin::Pin::new(read), removed);
1634
1635
                    if let Some(v) = opt {
1636
                        break 'outer Ok(v);
1637
                    }
1638
1639
                    match decoder
1640
                        .__before_parse_tokio_02(std::pin::Pin::new(&mut *read))
1641
                        .await
1642
                    {
1643
                        Ok(x) => x,
1644
                        Err(error) => {
1645
                            break 'outer Err($crate::stream::decoder::Error::Io {
1646
                                error,
1647
                                position: Clone::clone(decoder.position()),
1648
                            })
1649
                        }
1650
                    };
1651
                },
1652
            },
1653
        }
1654
    };
1655
}
1656
1657
/// Parses an instance of `tokio::io::AsyncRead` as a `&[u8]` without reading the entire file into
1658
/// memory.
1659
///
1660
/// This is defined as a macro to work around the lack of Higher Ranked Types. See the
1661
/// example for how to pass a parser to the macro (constructing parts of the parser outside of
1662
/// the `decode!` call is unlikely to work.
1663
///
1664
/// ```
1665
/// # use tokio_03_dep as tokio;
1666
/// # use futures_03_dep as futures;
1667
/// use futures::pin_mut;
1668
/// use tokio::{
1669
///     fs::File,
1670
/// };
1671
///
1672
/// use combine::{decode_tokio_03, satisfy, skip_many1, many1, sep_end_by, Parser, stream::{Decoder, buf_reader::BufReader}};
1673
///
1674
/// #[tokio::main]
1675
/// async fn main() {
1676
///     let mut read = BufReader::new(File::open("README.md").await.unwrap());
1677
///     let mut decoder = Decoder::new_bufferless();
1678
///     let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
1679
///     assert_eq!(
1680
///         decode_tokio_03!(
1681
///             decoder,
1682
///             read,
1683
///             {
1684
///                 let word = many1(satisfy(|b| !is_whitespace(b)));
1685
///                 sep_end_by(word, skip_many1(satisfy(is_whitespace))).map(|words: Vec<Vec<u8>>| words.len())
1686
///             },
1687
///             |input, _position| combine::easy::Stream::from(input),
1688
///         ).map_err(combine::easy::Errors::<u8, &[u8], _>::from),
1689
///         Ok(773),
1690
///     );
1691
/// }
1692
/// ```
1693
#[cfg(feature = "tokio-03")]
1694
#[cfg_attr(docsrs, doc(cfg(feature = "tokio-03")))]
1695
#[macro_export]
1696
macro_rules! decode_tokio_03 {
1697
    ($decoder: expr, $read: expr, $parser: expr $(,)?) => {
1698
        $crate::decode_tokio_03!($decoder, $read, $parser, |input, _position| input)
1699
    };
1700
1701
    ($decoder: expr, $read: expr, $parser: expr, $input_stream: expr $(,)?) => {
1702
        $crate::decode_tokio_03!($decoder, $read, $parser, $input_stream, |x| x)
1703
    };
1704
1705
    ($decoder: expr, $read: expr, $parser: expr, $input_stream: expr, $post_decode: expr $(,)?) => {
1706
        match $decoder {
1707
            ref mut decoder => match $read {
1708
                ref mut read => 'outer: loop {
1709
                    let (opt, removed) = {
1710
                        let (state, position, buffer, end_of_input) = decoder.__inner();
1711
                        let buffer =
1712
                            $crate::stream::buf_reader::CombineBuffer::buffer(buffer, &*read);
1713
                        let mut stream = $crate::stream::call_with2(
1714
                            $crate::stream::MaybePartialStream(buffer, !end_of_input),
1715
                            *position,
1716
                            $input_stream,
1717
                        );
1718
                        let result = $crate::stream::decode($parser, &mut stream, state);
1719
                        *position = $crate::stream::Positioned::position(&stream);
1720
                        $crate::stream::call_with(stream, $post_decode);
1721
                        match result {
1722
                            Ok(x) => x,
1723
                            Err(err) => {
1724
                                break 'outer Err($crate::stream::decoder::Error::Parse(err))
1725
                            }
1726
                        }
1727
                    };
1728
1729
                    decoder.advance_pin(std::pin::Pin::new(read), removed);
1730
1731
                    if let Some(v) = opt {
1732
                        break 'outer Ok(v);
1733
                    }
1734
1735
                    match decoder
1736
                        .__before_parse_tokio_03(std::pin::Pin::new(&mut *read))
1737
                        .await
1738
                    {
1739
                        Ok(x) => x,
1740
                        Err(error) => {
1741
                            break 'outer Err($crate::stream::decoder::Error::Io {
1742
                                error,
1743
                                position: Clone::clone(decoder.position()),
1744
                            })
1745
                        }
1746
                    };
1747
                },
1748
            },
1749
        }
1750
    };
1751
}
1752
1753
/// Parses an instance of `tokio::io::AsyncRead` as a `&[u8]` without reading the entire file into
1754
/// memory.
1755
///
1756
/// This is defined as a macro to work around the lack of Higher Ranked Types. See the
1757
/// example for how to pass a parser to the macro (constructing parts of the parser outside of
1758
/// the `decode!` call is unlikely to work.
1759
///
1760
/// ```
1761
/// # use tokio_dep as tokio;
1762
/// # use futures_03_dep as futures;
1763
/// use futures::pin_mut;
1764
/// use tokio::{
1765
///     fs::File,
1766
/// };
1767
///
1768
/// use combine::{decode_tokio, satisfy, skip_many1, many1, sep_end_by, Parser, stream::{Decoder, buf_reader::BufReader}};
1769
///
1770
/// #[tokio::main]
1771
/// async fn main() {
1772
///     let mut read = BufReader::new(File::open("README.md").await.unwrap());
1773
///     let mut decoder = Decoder::new_bufferless();
1774
///     let is_whitespace = |b: u8| b == b' ' || b == b'\r' || b == b'\n';
1775
///     assert_eq!(
1776
///         decode_tokio!(
1777
///             decoder,
1778
///             read,
1779
///             {
1780
///                 let word = many1(satisfy(|b| !is_whitespace(b)));
1781
///                 sep_end_by(word, skip_many1(satisfy(is_whitespace))).map(|words: Vec<Vec<u8>>| words.len())
1782
///             },
1783
///             |input, _position| combine::easy::Stream::from(input),
1784
///         ).map_err(combine::easy::Errors::<u8, &[u8], _>::from),
1785
///         Ok(773),
1786
///     );
1787
/// }
1788
/// ```
1789
#[cfg(feature = "tokio")]
1790
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
1791
#[macro_export]
1792
macro_rules! decode_tokio {
1793
    ($decoder: expr, $read: expr, $parser: expr $(,)?) => {
1794
        $crate::decode_tokio!($decoder, $read, $parser, |input, _position| input)
1795
    };
1796
1797
    ($decoder: expr, $read: expr, $parser: expr, $input_stream: expr $(,)?) => {
1798
        $crate::decode_tokio!($decoder, $read, $parser, $input_stream, |x| x)
1799
    };
1800
1801
    ($decoder: expr, $read: expr, $parser: expr, $input_stream: expr, $post_decode: expr $(,)?) => {
1802
        match $decoder {
1803
            ref mut decoder => match $read {
1804
                ref mut read => 'outer: loop {
1805
                    let (opt, removed) = {
1806
                        let (state, position, buffer, end_of_input) = decoder.__inner();
1807
                        let buffer =
1808
                            $crate::stream::buf_reader::CombineBuffer::buffer(buffer, &*read);
1809
                        let mut stream = $crate::stream::call_with2(
1810
                            $crate::stream::MaybePartialStream(buffer, !end_of_input),
1811
                            *position,
1812
                            $input_stream,
1813
                        );
1814
                        let result = $crate::stream::decode($parser, &mut stream, state);
1815
                        *position = $crate::stream::Positioned::position(&stream);
1816
                        $crate::stream::call_with(stream, $post_decode);
1817
                        match result {
1818
                            Ok(x) => x,
1819
                            Err(err) => {
1820
                                break 'outer Err($crate::stream::decoder::Error::Parse(err))
1821
                            }
1822
                        }
1823
                    };
1824
1825
                    decoder.advance_pin(std::pin::Pin::new(read), removed);
1826
1827
                    if let Some(v) = opt {
1828
                        break 'outer Ok(v);
1829
                    }
1830
1831
                    match decoder
1832
                        .__before_parse_tokio(std::pin::Pin::new(&mut *read))
1833
                        .await
1834
                    {
1835
                        Ok(x) => x,
1836
                        Err(error) => {
1837
                            break 'outer Err($crate::stream::decoder::Error::Io {
1838
                                error,
1839
                                position: Clone::clone(decoder.position()),
1840
                            })
1841
                        }
1842
                    };
1843
                },
1844
            },
1845
        }
1846
    };
1847
}
1848
1849
#[doc(hidden)]
1850
54.2k
pub fn call_with2<F, A, B, R>(a: A, b: B, f: F) -> R
1851
54.2k
where
1852
54.2k
    F: FnOnce(A, B) -> R,
1853
{
1854
54.2k
    f(a, b)
1855
54.2k
}
Unexecuted instantiation: combine::stream::call_with2::<<redis::parser::Parser>::parse_value<&mut std::net::tcp::TcpStream>::{closure#0}, combine::stream::MaybePartialStream<&[u8]>, combine::stream::PointerOffset<[u8]>, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
Unexecuted instantiation: combine::stream::call_with2::<<redis::parser::Parser>::parse_value<&mut std::os::unix::net::stream::UnixStream>::{closure#0}, combine::stream::MaybePartialStream<&[u8]>, combine::stream::PointerOffset<[u8]>, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
combine::stream::call_with2::<<redis::parser::Parser>::parse_value<&[u8]>::{closure#0}, combine::stream::MaybePartialStream<&[u8]>, combine::stream::PointerOffset<[u8]>, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
Line
Count
Source
1850
54.2k
pub fn call_with2<F, A, B, R>(a: A, b: B, f: F) -> R
1851
54.2k
where
1852
54.2k
    F: FnOnce(A, B) -> R,
1853
{
1854
54.2k
    f(a, b)
1855
54.2k
}
Unexecuted instantiation: combine::stream::call_with2::<_, _, _, _>
1856
1857
#[doc(hidden)]
1858
54.2k
pub fn call_with<F, A, R>(a: A, f: F) -> R
1859
54.2k
where
1860
54.2k
    F: FnOnce(A) -> R,
1861
{
1862
54.2k
    f(a)
1863
54.2k
}
Unexecuted instantiation: combine::stream::call_with::<<redis::parser::Parser>::parse_value<&mut std::net::tcp::TcpStream>::{closure#1}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
Unexecuted instantiation: combine::stream::call_with::<<redis::parser::Parser>::parse_value<&mut std::os::unix::net::stream::UnixStream>::{closure#1}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
combine::stream::call_with::<<redis::parser::Parser>::parse_value<&[u8]>::{closure#1}, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>, combine::stream::easy::Stream<combine::stream::MaybePartialStream<&[u8]>>>
Line
Count
Source
1858
54.2k
pub fn call_with<F, A, R>(a: A, f: F) -> R
1859
54.2k
where
1860
54.2k
    F: FnOnce(A) -> R,
1861
{
1862
54.2k
    f(a)
1863
54.2k
}
Unexecuted instantiation: combine::stream::call_with::<_, _, _>
1864
1865
#[cfg(test)]
1866
mod tests {
1867
1868
    use super::*;
1869
1870
    #[test]
1871
    #[inline]
1872
    fn uncons_range_at_end() {
1873
        assert_eq!("".uncons_range(0), Ok(""));
1874
        assert_eq!("123".uncons_range(3), Ok("123"));
1875
        assert_eq!((&[1][..]).uncons_range(1), Ok(&[1][..]));
1876
        let s: &[u8] = &[];
1877
        assert_eq!(SliceStream(s).uncons_range(0), Ok(&[][..]));
1878
    }
1879
1880
    #[test]
1881
    fn larger_than_1_byte_items_return_correct_distance() {
1882
        let mut input = &[123i32, 0i32][..];
1883
1884
        let before = input.checkpoint();
1885
        assert_eq!(input.distance(&before), 0);
1886
1887
        input.uncons().unwrap();
1888
        assert_eq!(input.distance(&before), 1);
1889
1890
        input.uncons().unwrap();
1891
        assert_eq!(input.distance(&before), 2);
1892
1893
        input.reset(before).unwrap();
1894
        assert_eq!(input.distance(&before), 0);
1895
    }
1896
}