Coverage Report

Created: 2026-02-14 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.6/src/stream/mod.rs
Line
Count
Source
1
//! Stream capability for combinators to parse
2
//!
3
//! Stream types include:
4
//! - `&[u8]` and [`Bytes`] for binary data
5
//! - `&str` (aliased as [`Str`]) and [`BStr`] for UTF-8 data
6
//! - [`LocatingSlice`] can track the location within the original buffer to report
7
//!   [spans][crate::Parser::with_span]
8
//! - [`Stateful`] to thread global state through your parsers
9
//! - [`Partial`] can mark an input as partial buffer that is being streamed into
10
//! - [Custom stream types][crate::_topic::stream]
11
12
use core::hash::BuildHasher;
13
use core::num::NonZeroUsize;
14
15
use crate::ascii::Caseless as AsciiCaseless;
16
use crate::error::Needed;
17
use crate::lib::std::iter::{Cloned, Enumerate};
18
use crate::lib::std::slice::Iter;
19
use crate::lib::std::str::from_utf8;
20
use crate::lib::std::str::CharIndices;
21
use crate::lib::std::str::FromStr;
22
23
#[allow(unused_imports)]
24
#[cfg(any(feature = "unstable-doc", feature = "unstable-recover"))]
25
use crate::error::ErrMode;
26
27
#[cfg(feature = "alloc")]
28
use crate::lib::std::collections::BTreeMap;
29
#[cfg(feature = "alloc")]
30
use crate::lib::std::collections::BTreeSet;
31
#[cfg(feature = "std")]
32
use crate::lib::std::collections::HashMap;
33
#[cfg(feature = "std")]
34
use crate::lib::std::collections::HashSet;
35
#[cfg(feature = "alloc")]
36
use crate::lib::std::string::String;
37
#[cfg(feature = "alloc")]
38
use crate::lib::std::vec::Vec;
39
40
mod bstr;
41
mod bytes;
42
mod locating;
43
mod partial;
44
mod range;
45
#[cfg(feature = "unstable-recover")]
46
#[cfg(feature = "std")]
47
mod recoverable;
48
mod stateful;
49
#[cfg(test)]
50
mod tests;
51
mod token;
52
53
pub use bstr::BStr;
54
pub use bytes::Bytes;
55
pub use locating::LocatingSlice;
56
pub use partial::Partial;
57
pub use range::Range;
58
#[cfg(feature = "unstable-recover")]
59
#[cfg(feature = "std")]
60
pub use recoverable::Recoverable;
61
pub use stateful::Stateful;
62
pub use token::TokenSlice;
63
64
/// UTF-8 Stream
65
pub type Str<'i> = &'i str;
66
67
/// Abstract method to calculate the input length
68
pub trait SliceLen {
69
    /// Calculates the input length, as indicated by its name,
70
    /// and the name of the trait itself
71
    fn slice_len(&self) -> usize;
72
}
73
74
impl<S: SliceLen> SliceLen for AsciiCaseless<S> {
75
    #[inline(always)]
76
0
    fn slice_len(&self) -> usize {
77
0
        self.0.slice_len()
78
0
    }
79
}
80
81
impl<T> SliceLen for &[T] {
82
    #[inline(always)]
83
0
    fn slice_len(&self) -> usize {
84
0
        self.len()
85
0
    }
Unexecuted instantiation: <&[u8] as winnow::stream::SliceLen>::slice_len
Unexecuted instantiation: <&[_] as winnow::stream::SliceLen>::slice_len
86
}
87
88
impl<T, const LEN: usize> SliceLen for [T; LEN] {
89
    #[inline(always)]
90
0
    fn slice_len(&self) -> usize {
91
0
        self.len()
92
0
    }
93
}
94
95
impl<T, const LEN: usize> SliceLen for &[T; LEN] {
96
    #[inline(always)]
97
0
    fn slice_len(&self) -> usize {
98
0
        self.len()
99
0
    }
100
}
101
102
impl SliceLen for &str {
103
    #[inline(always)]
104
0
    fn slice_len(&self) -> usize {
105
0
        self.len()
106
0
    }
107
}
108
109
impl SliceLen for u8 {
110
    #[inline(always)]
111
0
    fn slice_len(&self) -> usize {
112
0
        1
113
0
    }
114
}
115
116
impl SliceLen for char {
117
    #[inline(always)]
118
0
    fn slice_len(&self) -> usize {
119
0
        self.len_utf8()
120
0
    }
121
}
122
123
impl<I> SliceLen for (I, usize, usize)
124
where
125
    I: SliceLen,
126
{
127
    #[inline(always)]
128
0
    fn slice_len(&self) -> usize {
129
0
        self.0.slice_len() * 8 + self.2 - self.1
130
0
    }
131
}
132
133
/// Core definition for parser input state
134
pub trait Stream: Offset<<Self as Stream>::Checkpoint> + crate::lib::std::fmt::Debug {
135
    /// The smallest unit being parsed
136
    ///
137
    /// Example: `u8` for `&[u8]` or `char` for `&str`
138
    type Token: crate::lib::std::fmt::Debug;
139
    /// Sequence of `Token`s
140
    ///
141
    /// Example: `&[u8]` for `LocatingSlice<&[u8]>` or `&str` for `LocatingSlice<&str>`
142
    type Slice: crate::lib::std::fmt::Debug;
143
144
    /// Iterate with the offset from the current location
145
    type IterOffsets: Iterator<Item = (usize, Self::Token)>;
146
147
    /// A parse location within the stream
148
    type Checkpoint: Offset + Clone + crate::lib::std::fmt::Debug;
149
150
    /// Iterate with the offset from the current location
151
    fn iter_offsets(&self) -> Self::IterOffsets;
152
153
    /// Returns the offset to the end of the input
154
    fn eof_offset(&self) -> usize;
155
156
    /// Split off the next token from the input
157
    fn next_token(&mut self) -> Option<Self::Token>;
158
    /// Split off the next token from the input
159
    fn peek_token(&self) -> Option<Self::Token>;
160
161
    /// Finds the offset of the next matching token
162
    fn offset_for<P>(&self, predicate: P) -> Option<usize>
163
    where
164
        P: Fn(Self::Token) -> bool;
165
    /// Get the offset for the number of `tokens` into the stream
166
    ///
167
    /// This means "0 tokens" will return `0` offset
168
    fn offset_at(&self, tokens: usize) -> Result<usize, Needed>;
169
    /// Split off a slice of tokens from the input
170
    ///
171
    /// <div class="warning">
172
    ///
173
    /// **Note:** For inputs with variable width tokens, like `&str`'s `char`, `offset` might not correspond
174
    /// with the number of tokens. To get a valid offset, use:
175
    /// - [`Stream::eof_offset`]
176
    /// - [`Stream::iter_offsets`]
177
    /// - [`Stream::offset_for`]
178
    /// - [`Stream::offset_at`]
179
    ///
180
    /// </div>
181
    ///
182
    /// # Panic
183
    ///
184
    /// This will panic if
185
    ///
186
    /// * Indexes must be within bounds of the original input;
187
    /// * Indexes must uphold invariants of the stream, like for `str` they must lie on UTF-8
188
    ///   sequence boundaries.
189
    ///
190
    fn next_slice(&mut self, offset: usize) -> Self::Slice;
191
    /// Split off a slice of tokens from the input
192
    ///
193
    /// <div class="warning">
194
    ///
195
    /// **Note:** For inputs with variable width tokens, like `&str`'s `char`, `offset` might not correspond
196
    /// with the number of tokens. To get a valid offset, use:
197
    /// - [`Stream::eof_offset`]
198
    /// - [`Stream::iter_offsets`]
199
    /// - [`Stream::offset_for`]
200
    /// - [`Stream::offset_at`]
201
    ///
202
    /// </div>
203
    ///
204
    /// # Safety
205
    ///
206
    /// Callers of this function are responsible that these preconditions are satisfied:
207
    ///
208
    /// * Indexes must be within bounds of the original input;
209
    /// * Indexes must uphold invariants of the stream, like for `str` they must lie on UTF-8
210
    ///   sequence boundaries.
211
    ///
212
0
    unsafe fn next_slice_unchecked(&mut self, offset: usize) -> Self::Slice {
213
        // Inherent impl to allow callers to have `unsafe`-free code
214
0
        self.next_slice(offset)
215
0
    }
216
    /// Split off a slice of tokens from the input
217
    fn peek_slice(&self, offset: usize) -> Self::Slice;
218
    /// Split off a slice of tokens from the input
219
    ///
220
    /// # Safety
221
    ///
222
    /// Callers of this function are responsible that these preconditions are satisfied:
223
    ///
224
    /// * Indexes must be within bounds of the original input;
225
    /// * Indexes must uphold invariants of the stream, like for `str` they must lie on UTF-8
226
    ///   sequence boundaries.
227
0
    unsafe fn peek_slice_unchecked(&self, offset: usize) -> Self::Slice {
228
        // Inherent impl to allow callers to have `unsafe`-free code
229
0
        self.peek_slice(offset)
230
0
    }
231
232
    /// Advance to the end of the stream
233
    #[inline(always)]
234
0
    fn finish(&mut self) -> Self::Slice {
235
0
        self.next_slice(self.eof_offset())
236
0
    }
Unexecuted instantiation: <&str as winnow::stream::Stream>::finish
Unexecuted instantiation: <_ as winnow::stream::Stream>::finish
237
    /// Advance to the end of the stream
238
    #[inline(always)]
239
0
    fn peek_finish(&self) -> Self::Slice
240
0
    where
241
0
        Self: Clone,
242
    {
243
0
        self.peek_slice(self.eof_offset())
244
0
    }
245
246
    /// Save the current parse location within the stream
247
    fn checkpoint(&self) -> Self::Checkpoint;
248
    /// Revert the stream to a prior [`Self::Checkpoint`]
249
    ///
250
    /// # Panic
251
    ///
252
    /// May panic if an invalid [`Self::Checkpoint`] is provided
253
    fn reset(&mut self, checkpoint: &Self::Checkpoint);
254
255
    /// Return the inner-most stream
256
    fn raw(&self) -> &dyn crate::lib::std::fmt::Debug;
257
}
258
259
impl<'i, T> Stream for &'i [T]
260
where
261
    T: Clone + crate::lib::std::fmt::Debug,
262
{
263
    type Token = T;
264
    type Slice = &'i [T];
265
266
    type IterOffsets = Enumerate<Cloned<Iter<'i, T>>>;
267
268
    type Checkpoint = Checkpoint<Self, Self>;
269
270
    #[inline(always)]
271
0
    fn iter_offsets(&self) -> Self::IterOffsets {
272
0
        self.iter().cloned().enumerate()
273
0
    }
274
    #[inline(always)]
275
0
    fn eof_offset(&self) -> usize {
276
0
        self.len()
277
0
    }
278
279
    #[inline(always)]
280
0
    fn next_token(&mut self) -> Option<Self::Token> {
281
0
        let (token, next) = self.split_first()?;
282
0
        *self = next;
283
0
        Some(token.clone())
284
0
    }
285
286
    #[inline(always)]
287
0
    fn peek_token(&self) -> Option<Self::Token> {
288
0
        if self.is_empty() {
289
0
            None
290
        } else {
291
0
            Some(self[0].clone())
292
        }
293
0
    }
294
295
    #[inline(always)]
296
0
    fn offset_for<P>(&self, predicate: P) -> Option<usize>
297
0
    where
298
0
        P: Fn(Self::Token) -> bool,
299
    {
300
0
        self.iter().position(|b| predicate(b.clone()))
301
0
    }
302
    #[inline(always)]
303
0
    fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
304
0
        if let Some(needed) = tokens.checked_sub(self.len()).and_then(NonZeroUsize::new) {
305
0
            Err(Needed::Size(needed))
306
        } else {
307
0
            Ok(tokens)
308
        }
309
0
    }
310
    #[inline(always)]
311
0
    fn next_slice(&mut self, offset: usize) -> Self::Slice {
312
0
        let (slice, next) = self.split_at(offset);
313
0
        *self = next;
314
0
        slice
315
0
    }
316
    #[inline(always)]
317
0
    unsafe fn next_slice_unchecked(&mut self, offset: usize) -> Self::Slice {
318
        #[cfg(debug_assertions)]
319
        self.peek_slice(offset);
320
321
        // SAFETY: `Stream::next_slice_unchecked` requires `offset` to be in bounds
322
0
        let slice = unsafe { self.get_unchecked(..offset) };
323
        // SAFETY: `Stream::next_slice_unchecked` requires `offset` to be in bounds
324
0
        let next = unsafe { self.get_unchecked(offset..) };
325
0
        *self = next;
326
0
        slice
327
0
    }
328
    #[inline(always)]
329
0
    fn peek_slice(&self, offset: usize) -> Self::Slice {
330
0
        &self[..offset]
331
0
    }
332
    #[inline(always)]
333
0
    unsafe fn peek_slice_unchecked(&self, offset: usize) -> Self::Slice {
334
        #[cfg(debug_assertions)]
335
        self.peek_slice(offset);
336
337
        // SAFETY: `Stream::next_slice_unchecked` requires `offset` to be in bounds
338
0
        let slice = unsafe { self.get_unchecked(..offset) };
339
0
        slice
340
0
    }
341
342
    #[inline(always)]
343
0
    fn checkpoint(&self) -> Self::Checkpoint {
344
0
        Checkpoint::<_, Self>::new(*self)
345
0
    }
346
    #[inline(always)]
347
0
    fn reset(&mut self, checkpoint: &Self::Checkpoint) {
348
0
        *self = checkpoint.inner;
349
0
    }
350
351
    #[inline(always)]
352
0
    fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
353
0
        self
354
0
    }
355
}
356
357
impl<'i> Stream for &'i str {
358
    type Token = char;
359
    type Slice = &'i str;
360
361
    type IterOffsets = CharIndices<'i>;
362
363
    type Checkpoint = Checkpoint<Self, Self>;
364
365
    #[inline(always)]
366
0
    fn iter_offsets(&self) -> Self::IterOffsets {
367
0
        self.char_indices()
368
0
    }
369
    #[inline(always)]
370
0
    fn eof_offset(&self) -> usize {
371
0
        self.len()
372
0
    }
373
374
    #[inline(always)]
375
0
    fn next_token(&mut self) -> Option<Self::Token> {
376
0
        let c = self.chars().next()?;
377
0
        let offset = c.len();
378
0
        *self = &self[offset..];
379
0
        Some(c)
380
0
    }
381
382
    #[inline(always)]
383
0
    fn peek_token(&self) -> Option<Self::Token> {
384
0
        self.chars().next()
385
0
    }
386
387
    #[inline(always)]
388
0
    fn offset_for<P>(&self, predicate: P) -> Option<usize>
389
0
    where
390
0
        P: Fn(Self::Token) -> bool,
391
    {
392
0
        for (o, c) in self.iter_offsets() {
393
0
            if predicate(c) {
394
0
                return Some(o);
395
0
            }
396
        }
397
0
        None
398
0
    }
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<winnow::token::take_while<duration_str::unit::unit_abbr1::{closure#0}, &str, winnow::error::ErrMode<winnow::error::ContextError>, core::ops::range::RangeFrom<usize>>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<winnow::token::take_while<duration_str::unit::unit_abbr1::{closure#0}, &str, winnow::error::ErrMode<winnow::error::ContextError>, core::ops::range::RangeFrom<usize>>::{closure#0}::{closure#2}>
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<winnow::token::take_while<duration_str::unit::unit_abbr1::{closure#0}, &str, winnow::error::ErrMode<winnow::error::ContextError>, core::ops::range::RangeFrom<usize>>::{closure#0}::{closure#3}>
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<winnow::token::take_while<duration_str::unit::unit_abbr1::{closure#0}, &str, winnow::error::ErrMode<winnow::error::ContextError>, core::ops::range::RangeFrom<usize>>::{closure#0}::{closure#1}>
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<winnow::token::take_while<<char as winnow::stream::AsChar>::is_dec_digit, &str, winnow::error::ErrMode<winnow::error::ContextError>, core::ops::range::RangeFrom<usize>>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<winnow::token::take_while<<char as winnow::stream::AsChar>::is_dec_digit, &str, winnow::error::ErrMode<winnow::error::ContextError>, core::ops::range::RangeFrom<usize>>::{closure#0}::{closure#2}>
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<winnow::token::take_while<<char as winnow::stream::AsChar>::is_dec_digit, &str, winnow::error::ErrMode<winnow::error::ContextError>, core::ops::range::RangeFrom<usize>>::{closure#0}::{closure#3}>
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<winnow::token::take_while<<char as winnow::stream::AsChar>::is_dec_digit, &str, winnow::error::ErrMode<winnow::error::ContextError>, core::ops::range::RangeFrom<usize>>::{closure#0}::{closure#1}>
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<winnow::token::take_while<(char, char, char, char), &str, winnow::error::ErrMode<winnow::error::ContextError>, core::ops::range::RangeFrom<usize>>::{closure#0}::{closure#0}>
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<winnow::token::take_while<(char, char, char, char), &str, winnow::error::ErrMode<winnow::error::ContextError>, core::ops::range::RangeFrom<usize>>::{closure#0}::{closure#2}>
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<winnow::token::take_while<(char, char, char, char), &str, winnow::error::ErrMode<winnow::error::ContextError>, core::ops::range::RangeFrom<usize>>::{closure#0}::{closure#3}>
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<winnow::token::take_while<(char, char, char, char), &str, winnow::error::ErrMode<winnow::error::ContextError>, core::ops::range::RangeFrom<usize>>::{closure#0}::{closure#1}>
Unexecuted instantiation: <&str as winnow::stream::Stream>::offset_for::<_>
399
    #[inline]
400
0
    fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
401
0
        let mut cnt = 0;
402
0
        for (offset, _) in self.iter_offsets() {
403
0
            if cnt == tokens {
404
0
                return Ok(offset);
405
0
            }
406
0
            cnt += 1;
407
        }
408
409
0
        if cnt == tokens {
410
0
            Ok(self.eof_offset())
411
        } else {
412
0
            Err(Needed::Unknown)
413
        }
414
0
    }
415
    #[inline(always)]
416
0
    fn next_slice(&mut self, offset: usize) -> Self::Slice {
417
0
        let (slice, next) = self.split_at(offset);
418
0
        *self = next;
419
0
        slice
420
0
    }
421
    #[inline(always)]
422
0
    unsafe fn next_slice_unchecked(&mut self, offset: usize) -> Self::Slice {
423
        #[cfg(debug_assertions)]
424
        self.peek_slice(offset);
425
426
        // SAFETY: `Stream::next_slice_unchecked` requires `offset` to be in bounds and on a UTF-8
427
        // sequence boundary
428
0
        let slice = unsafe { self.get_unchecked(..offset) };
429
        // SAFETY: `Stream::next_slice_unchecked` requires `offset` to be in bounds and on a UTF-8
430
        // sequence boundary
431
0
        let next = unsafe { self.get_unchecked(offset..) };
432
0
        *self = next;
433
0
        slice
434
0
    }
435
    #[inline(always)]
436
0
    fn peek_slice(&self, offset: usize) -> Self::Slice {
437
0
        &self[..offset]
438
0
    }
439
    #[inline(always)]
440
0
    unsafe fn peek_slice_unchecked(&self, offset: usize) -> Self::Slice {
441
        #[cfg(debug_assertions)]
442
        self.peek_slice(offset);
443
444
        // SAFETY: `Stream::next_slice_unchecked` requires `offset` to be in bounds
445
0
        let slice = unsafe { self.get_unchecked(..offset) };
446
0
        slice
447
0
    }
448
449
    #[inline(always)]
450
0
    fn checkpoint(&self) -> Self::Checkpoint {
451
0
        Checkpoint::<_, Self>::new(*self)
452
0
    }
453
    #[inline(always)]
454
0
    fn reset(&mut self, checkpoint: &Self::Checkpoint) {
455
0
        *self = checkpoint.inner;
456
0
    }
457
458
    #[inline(always)]
459
0
    fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
460
0
        self
461
0
    }
462
}
463
464
impl<I> Stream for (I, usize)
465
where
466
    I: Stream<Token = u8> + Clone,
467
{
468
    type Token = bool;
469
    type Slice = (I::Slice, usize, usize);
470
471
    type IterOffsets = BitOffsets<I>;
472
473
    type Checkpoint = Checkpoint<(I::Checkpoint, usize), Self>;
474
475
    #[inline(always)]
476
0
    fn iter_offsets(&self) -> Self::IterOffsets {
477
0
        BitOffsets {
478
0
            i: self.clone(),
479
0
            o: 0,
480
0
        }
481
0
    }
482
    #[inline(always)]
483
0
    fn eof_offset(&self) -> usize {
484
0
        let offset = self.0.eof_offset() * 8;
485
0
        if offset == 0 {
486
0
            0
487
        } else {
488
0
            offset - self.1
489
        }
490
0
    }
491
492
    #[inline(always)]
493
0
    fn next_token(&mut self) -> Option<Self::Token> {
494
0
        next_bit(self)
495
0
    }
496
497
    #[inline(always)]
498
0
    fn peek_token(&self) -> Option<Self::Token> {
499
0
        peek_bit(self)
500
0
    }
501
502
    #[inline(always)]
503
0
    fn offset_for<P>(&self, predicate: P) -> Option<usize>
504
0
    where
505
0
        P: Fn(Self::Token) -> bool,
506
    {
507
0
        self.iter_offsets()
508
0
            .find_map(|(o, b)| predicate(b).then_some(o))
509
0
    }
510
    #[inline(always)]
511
0
    fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
512
0
        if let Some(needed) = tokens
513
0
            .checked_sub(self.eof_offset())
514
0
            .and_then(NonZeroUsize::new)
515
        {
516
0
            Err(Needed::Size(needed))
517
        } else {
518
0
            Ok(tokens)
519
        }
520
0
    }
521
    #[inline(always)]
522
0
    fn next_slice(&mut self, offset: usize) -> Self::Slice {
523
0
        let byte_offset = (offset + self.1) / 8;
524
0
        let end_offset = (offset + self.1) % 8;
525
0
        let s = self.0.next_slice(byte_offset);
526
0
        let start_offset = self.1;
527
0
        self.1 = end_offset;
528
0
        (s, start_offset, end_offset)
529
0
    }
530
    #[inline(always)]
531
0
    fn peek_slice(&self, offset: usize) -> Self::Slice {
532
0
        let byte_offset = (offset + self.1) / 8;
533
0
        let end_offset = (offset + self.1) % 8;
534
0
        let s = self.0.peek_slice(byte_offset);
535
0
        let start_offset = self.1;
536
0
        (s, start_offset, end_offset)
537
0
    }
538
539
    #[inline(always)]
540
0
    fn checkpoint(&self) -> Self::Checkpoint {
541
0
        Checkpoint::<_, Self>::new((self.0.checkpoint(), self.1))
542
0
    }
543
    #[inline(always)]
544
0
    fn reset(&mut self, checkpoint: &Self::Checkpoint) {
545
0
        self.0.reset(&checkpoint.inner.0);
546
0
        self.1 = checkpoint.inner.1;
547
0
    }
548
549
    #[inline(always)]
550
0
    fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
551
0
        &self.0
552
0
    }
553
}
554
555
/// Iterator for [bit][crate::binary::bits] stream (`(I, usize)`)
556
pub struct BitOffsets<I> {
557
    i: (I, usize),
558
    o: usize,
559
}
560
561
impl<I> Iterator for BitOffsets<I>
562
where
563
    I: Stream<Token = u8> + Clone,
564
{
565
    type Item = (usize, bool);
566
0
    fn next(&mut self) -> Option<Self::Item> {
567
0
        let b = next_bit(&mut self.i)?;
568
0
        let o = self.o;
569
570
0
        self.o += 1;
571
572
0
        Some((o, b))
573
0
    }
574
}
575
576
0
fn next_bit<I>(i: &mut (I, usize)) -> Option<bool>
577
0
where
578
0
    I: Stream<Token = u8> + Clone,
579
{
580
0
    if i.eof_offset() == 0 {
581
0
        return None;
582
0
    }
583
0
    let offset = i.1;
584
585
0
    let mut next_i = i.0.clone();
586
0
    let byte = next_i.next_token()?;
587
0
    let bit = (byte >> offset) & 0x1 == 0x1;
588
589
0
    let next_offset = offset + 1;
590
0
    if next_offset == 8 {
591
0
        i.0 = next_i;
592
0
        i.1 = 0;
593
0
        Some(bit)
594
    } else {
595
0
        i.1 = next_offset;
596
0
        Some(bit)
597
    }
598
0
}
599
600
0
fn peek_bit<I>(i: &(I, usize)) -> Option<bool>
601
0
where
602
0
    I: Stream<Token = u8> + Clone,
603
{
604
0
    if i.eof_offset() == 0 {
605
0
        return None;
606
0
    }
607
0
    let offset = i.1;
608
609
0
    let mut next_i = i.0.clone();
610
0
    let byte = next_i.next_token()?;
611
0
    let bit = (byte >> offset) & 0x1 == 0x1;
612
613
0
    let next_offset = offset + 1;
614
0
    if next_offset == 8 {
615
0
        Some(bit)
616
    } else {
617
0
        Some(bit)
618
    }
619
0
}
620
621
/// Current parse locations offset
622
///
623
/// See [`LocatingSlice`] for adding location tracking to your [`Stream`]
624
pub trait Location {
625
    /// Previous token's end offset
626
    fn previous_token_end(&self) -> usize;
627
    /// Current token's start offset
628
    fn current_token_start(&self) -> usize;
629
}
630
631
/// Capture top-level errors in the middle of parsing so parsing can resume
632
///
633
/// See [`Recoverable`] for adding error recovery tracking to your [`Stream`]
634
#[cfg(feature = "unstable-recover")]
635
#[cfg(feature = "std")]
636
pub trait Recover<E>: Stream {
637
    /// Capture a top-level error
638
    ///
639
    /// May return `Err(err)` if recovery is not possible (e.g. if [`Recover::is_recovery_supported`]
640
    /// returns `false`).
641
    fn record_err(
642
        &mut self,
643
        token_start: &Self::Checkpoint,
644
        err_start: &Self::Checkpoint,
645
        err: E,
646
    ) -> Result<(), E>;
647
648
    /// Report whether the [`Stream`] can save off errors for recovery
649
    fn is_recovery_supported() -> bool;
650
}
651
652
#[cfg(feature = "unstable-recover")]
653
#[cfg(feature = "std")]
654
impl<'a, T, E> Recover<E> for &'a [T]
655
where
656
    &'a [T]: Stream,
657
{
658
    #[inline(always)]
659
    fn record_err(
660
        &mut self,
661
        _token_start: &Self::Checkpoint,
662
        _err_start: &Self::Checkpoint,
663
        err: E,
664
    ) -> Result<(), E> {
665
        Err(err)
666
    }
667
668
    /// Report whether the [`Stream`] can save off errors for recovery
669
    #[inline(always)]
670
    fn is_recovery_supported() -> bool {
671
        false
672
    }
673
}
674
675
#[cfg(feature = "unstable-recover")]
676
#[cfg(feature = "std")]
677
impl<E> Recover<E> for &str {
678
    #[inline(always)]
679
    fn record_err(
680
        &mut self,
681
        _token_start: &Self::Checkpoint,
682
        _err_start: &Self::Checkpoint,
683
        err: E,
684
    ) -> Result<(), E> {
685
        Err(err)
686
    }
687
688
    /// Report whether the [`Stream`] can save off errors for recovery
689
    #[inline(always)]
690
    fn is_recovery_supported() -> bool {
691
        false
692
    }
693
}
694
695
#[cfg(feature = "unstable-recover")]
696
#[cfg(feature = "std")]
697
impl<I, E> Recover<E> for (I, usize)
698
where
699
    I: Recover<E>,
700
    I: Stream<Token = u8> + Clone,
701
{
702
    #[inline(always)]
703
    fn record_err(
704
        &mut self,
705
        _token_start: &Self::Checkpoint,
706
        _err_start: &Self::Checkpoint,
707
        err: E,
708
    ) -> Result<(), E> {
709
        Err(err)
710
    }
711
712
    /// Report whether the [`Stream`] can save off errors for recovery
713
    #[inline(always)]
714
    fn is_recovery_supported() -> bool {
715
        false
716
    }
717
}
718
719
/// Marks the input as being the complete buffer or a partial buffer for streaming input
720
///
721
/// See [`Partial`] for marking a presumed complete buffer type as a streaming buffer.
722
pub trait StreamIsPartial: Sized {
723
    /// Whether the stream is currently partial or complete
724
    type PartialState;
725
726
    /// Mark the stream is complete
727
    #[must_use]
728
    fn complete(&mut self) -> Self::PartialState;
729
730
    /// Restore the stream back to its previous state
731
    fn restore_partial(&mut self, state: Self::PartialState);
732
733
    /// Report whether the [`Stream`] is can ever be incomplete
734
    fn is_partial_supported() -> bool;
735
736
    /// Report whether the [`Stream`] is currently incomplete
737
    #[inline(always)]
738
0
    fn is_partial(&self) -> bool {
739
0
        Self::is_partial_supported()
740
0
    }
Unexecuted instantiation: <&str as winnow::stream::StreamIsPartial>::is_partial
Unexecuted instantiation: <_ as winnow::stream::StreamIsPartial>::is_partial
741
}
742
743
impl<T> StreamIsPartial for &[T] {
744
    type PartialState = ();
745
746
    #[inline]
747
0
    fn complete(&mut self) -> Self::PartialState {}
748
749
    #[inline]
750
0
    fn restore_partial(&mut self, _state: Self::PartialState) {}
751
752
    #[inline(always)]
753
0
    fn is_partial_supported() -> bool {
754
0
        false
755
0
    }
756
}
757
758
impl StreamIsPartial for &str {
759
    type PartialState = ();
760
761
    #[inline]
762
0
    fn complete(&mut self) -> Self::PartialState {
763
        // Already complete
764
0
    }
765
766
    #[inline]
767
0
    fn restore_partial(&mut self, _state: Self::PartialState) {}
768
769
    #[inline(always)]
770
0
    fn is_partial_supported() -> bool {
771
0
        false
772
0
    }
773
}
774
775
impl<I> StreamIsPartial for (I, usize)
776
where
777
    I: StreamIsPartial,
778
{
779
    type PartialState = I::PartialState;
780
781
    #[inline]
782
0
    fn complete(&mut self) -> Self::PartialState {
783
0
        self.0.complete()
784
0
    }
785
786
    #[inline]
787
0
    fn restore_partial(&mut self, state: Self::PartialState) {
788
0
        self.0.restore_partial(state);
789
0
    }
790
791
    #[inline(always)]
792
0
    fn is_partial_supported() -> bool {
793
0
        I::is_partial_supported()
794
0
    }
795
796
    #[inline(always)]
797
0
    fn is_partial(&self) -> bool {
798
0
        self.0.is_partial()
799
0
    }
800
}
801
802
/// Useful functions to calculate the offset between slices and show a hexdump of a slice
803
pub trait Offset<Start = Self> {
804
    /// Offset between the first byte of `start` and the first byte of `self`a
805
    ///
806
    /// <div class="warning">
807
    ///
808
    /// **Note:** This is an offset, not an index, and may point to the end of input
809
    /// (`start.len()`) when `self` is exhausted.
810
    ///
811
    /// </div>
812
    fn offset_from(&self, start: &Start) -> usize;
813
}
814
815
impl<T> Offset for &[T] {
816
    #[inline]
817
0
    fn offset_from(&self, start: &Self) -> usize {
818
0
        let fst = (*start).as_ptr();
819
0
        let snd = (*self).as_ptr();
820
821
0
        debug_assert!(
822
0
            fst <= snd,
823
0
            "`Offset::offset_from({snd:?}, {fst:?})` only accepts slices of `self`"
824
        );
825
0
        (snd as usize - fst as usize) / crate::lib::std::mem::size_of::<T>()
826
0
    }
Unexecuted instantiation: <&[u8] as winnow::stream::Offset>::offset_from
Unexecuted instantiation: <&[_] as winnow::stream::Offset>::offset_from
827
}
828
829
impl<'a, T> Offset<<&'a [T] as Stream>::Checkpoint> for &'a [T]
830
where
831
    T: Clone + crate::lib::std::fmt::Debug,
832
{
833
    #[inline(always)]
834
0
    fn offset_from(&self, other: &<&'a [T] as Stream>::Checkpoint) -> usize {
835
0
        self.checkpoint().offset_from(other)
836
0
    }
837
}
838
839
impl Offset for &str {
840
    #[inline(always)]
841
0
    fn offset_from(&self, start: &Self) -> usize {
842
0
        self.as_bytes().offset_from(&start.as_bytes())
843
0
    }
844
}
845
846
impl<'a> Offset<<&'a str as Stream>::Checkpoint> for &'a str {
847
    #[inline(always)]
848
0
    fn offset_from(&self, other: &<&'a str as Stream>::Checkpoint) -> usize {
849
0
        self.checkpoint().offset_from(other)
850
0
    }
851
}
852
853
impl<I> Offset for (I, usize)
854
where
855
    I: Offset,
856
{
857
    #[inline(always)]
858
0
    fn offset_from(&self, start: &Self) -> usize {
859
0
        self.0.offset_from(&start.0) * 8 + self.1 - start.1
860
0
    }
861
}
862
863
impl<I> Offset<<(I, usize) as Stream>::Checkpoint> for (I, usize)
864
where
865
    I: Stream<Token = u8> + Clone,
866
{
867
    #[inline(always)]
868
0
    fn offset_from(&self, other: &<(I, usize) as Stream>::Checkpoint) -> usize {
869
0
        self.checkpoint().offset_from(other)
870
0
    }
871
}
872
873
impl<I, S> Offset for Checkpoint<I, S>
874
where
875
    I: Offset,
876
{
877
    #[inline(always)]
878
0
    fn offset_from(&self, start: &Self) -> usize {
879
0
        self.inner.offset_from(&start.inner)
880
0
    }
Unexecuted instantiation: <winnow::stream::Checkpoint<&str, &str> as winnow::stream::Offset>::offset_from
Unexecuted instantiation: <winnow::stream::Checkpoint<_, _> as winnow::stream::Offset>::offset_from
881
}
882
883
/// Helper trait for types that can be viewed as a byte slice
884
pub trait AsBytes {
885
    /// Casts the input type to a byte slice
886
    fn as_bytes(&self) -> &[u8];
887
}
888
889
impl AsBytes for &[u8] {
890
    #[inline(always)]
891
0
    fn as_bytes(&self) -> &[u8] {
892
0
        self
893
0
    }
894
}
895
896
/// Helper trait for types that can be viewed as a byte slice
897
pub trait AsBStr {
898
    /// Casts the input type to a byte slice
899
    fn as_bstr(&self) -> &[u8];
900
}
901
902
impl AsBStr for &[u8] {
903
    #[inline(always)]
904
0
    fn as_bstr(&self) -> &[u8] {
905
0
        self
906
0
    }
907
}
908
909
impl AsBStr for &str {
910
    #[inline(always)]
911
0
    fn as_bstr(&self) -> &[u8] {
912
0
        (*self).as_bytes()
913
0
    }
914
}
915
916
/// Result of [`Compare::compare`]
917
#[derive(Debug, Eq, PartialEq)]
918
pub enum CompareResult {
919
    /// Comparison was successful
920
    ///
921
    /// `usize` is the end of the successful match within the buffer.
922
    /// This is most relevant for caseless UTF-8 where `Compare::compare`'s parameter might be a different
923
    /// length than the match within the buffer.
924
    Ok(usize),
925
    /// We need more data to be sure
926
    Incomplete,
927
    /// Comparison failed
928
    Error,
929
}
930
931
/// Abstracts comparison operations
932
pub trait Compare<T> {
933
    /// Compares self to another value for equality
934
    fn compare(&self, t: T) -> CompareResult;
935
}
936
937
impl<'b> Compare<&'b [u8]> for &[u8] {
938
    #[inline]
939
0
    fn compare(&self, t: &'b [u8]) -> CompareResult {
940
0
        if t.iter().zip(*self).any(|(a, b)| a != b) {
Unexecuted instantiation: <&[u8] as winnow::stream::Compare<&[u8]>>::compare::{closure#0}
Unexecuted instantiation: <&[u8] as winnow::stream::Compare<&[u8]>>::compare::{closure#0}
941
0
            CompareResult::Error
942
0
        } else if self.len() < t.slice_len() {
943
0
            CompareResult::Incomplete
944
        } else {
945
0
            CompareResult::Ok(t.slice_len())
946
        }
947
0
    }
Unexecuted instantiation: <&[u8] as winnow::stream::Compare<&[u8]>>::compare
Unexecuted instantiation: <&[u8] as winnow::stream::Compare<&[u8]>>::compare
948
}
949
950
impl<'b> Compare<AsciiCaseless<&'b [u8]>> for &[u8] {
951
    #[inline]
952
0
    fn compare(&self, t: AsciiCaseless<&'b [u8]>) -> CompareResult {
953
0
        if t.0
954
0
            .iter()
955
0
            .zip(*self)
956
0
            .any(|(a, b)| !a.eq_ignore_ascii_case(b))
957
        {
958
0
            CompareResult::Error
959
0
        } else if self.len() < t.slice_len() {
960
0
            CompareResult::Incomplete
961
        } else {
962
0
            CompareResult::Ok(t.slice_len())
963
        }
964
0
    }
965
}
966
967
impl<const LEN: usize> Compare<[u8; LEN]> for &[u8] {
968
    #[inline(always)]
969
0
    fn compare(&self, t: [u8; LEN]) -> CompareResult {
970
0
        self.compare(&t[..])
971
0
    }
972
}
973
974
impl<const LEN: usize> Compare<AsciiCaseless<[u8; LEN]>> for &[u8] {
975
    #[inline(always)]
976
0
    fn compare(&self, t: AsciiCaseless<[u8; LEN]>) -> CompareResult {
977
0
        self.compare(AsciiCaseless(&t.0[..]))
978
0
    }
979
}
980
981
impl<'b, const LEN: usize> Compare<&'b [u8; LEN]> for &[u8] {
982
    #[inline(always)]
983
0
    fn compare(&self, t: &'b [u8; LEN]) -> CompareResult {
984
0
        self.compare(&t[..])
985
0
    }
986
}
987
988
impl<'b, const LEN: usize> Compare<AsciiCaseless<&'b [u8; LEN]>> for &[u8] {
989
    #[inline(always)]
990
0
    fn compare(&self, t: AsciiCaseless<&'b [u8; LEN]>) -> CompareResult {
991
0
        self.compare(AsciiCaseless(&t.0[..]))
992
0
    }
993
}
994
995
impl<'b> Compare<&'b str> for &[u8] {
996
    #[inline(always)]
997
0
    fn compare(&self, t: &'b str) -> CompareResult {
998
0
        self.compare(t.as_bytes())
999
0
    }
1000
}
1001
1002
impl<'b> Compare<AsciiCaseless<&'b str>> for &[u8] {
1003
    #[inline(always)]
1004
0
    fn compare(&self, t: AsciiCaseless<&'b str>) -> CompareResult {
1005
0
        self.compare(AsciiCaseless(t.0.as_bytes()))
1006
0
    }
1007
}
1008
1009
impl Compare<u8> for &[u8] {
1010
    #[inline]
1011
0
    fn compare(&self, t: u8) -> CompareResult {
1012
0
        match self.first().copied() {
1013
0
            Some(c) if t == c => CompareResult::Ok(t.slice_len()),
1014
0
            Some(_) => CompareResult::Error,
1015
0
            None => CompareResult::Incomplete,
1016
        }
1017
0
    }
1018
}
1019
1020
impl Compare<AsciiCaseless<u8>> for &[u8] {
1021
    #[inline]
1022
0
    fn compare(&self, t: AsciiCaseless<u8>) -> CompareResult {
1023
0
        match self.first() {
1024
0
            Some(c) if t.0.eq_ignore_ascii_case(c) => CompareResult::Ok(t.slice_len()),
1025
0
            Some(_) => CompareResult::Error,
1026
0
            None => CompareResult::Incomplete,
1027
        }
1028
0
    }
1029
}
1030
1031
impl Compare<char> for &[u8] {
1032
    #[inline(always)]
1033
0
    fn compare(&self, t: char) -> CompareResult {
1034
0
        self.compare(t.encode_utf8(&mut [0; 4]).as_bytes())
1035
0
    }
1036
}
1037
1038
impl Compare<AsciiCaseless<char>> for &[u8] {
1039
    #[inline(always)]
1040
0
    fn compare(&self, t: AsciiCaseless<char>) -> CompareResult {
1041
0
        self.compare(AsciiCaseless(t.0.encode_utf8(&mut [0; 4]).as_bytes()))
1042
0
    }
1043
}
1044
1045
impl<'b> Compare<&'b str> for &str {
1046
    #[inline(always)]
1047
0
    fn compare(&self, t: &'b str) -> CompareResult {
1048
0
        self.as_bytes().compare(t.as_bytes())
1049
0
    }
1050
}
1051
1052
impl<'b> Compare<AsciiCaseless<&'b str>> for &str {
1053
    #[inline(always)]
1054
0
    fn compare(&self, t: AsciiCaseless<&'b str>) -> CompareResult {
1055
0
        self.as_bytes().compare(t.as_bytes())
1056
0
    }
1057
}
1058
1059
impl Compare<char> for &str {
1060
    #[inline(always)]
1061
0
    fn compare(&self, t: char) -> CompareResult {
1062
0
        self.as_bytes().compare(t)
1063
0
    }
1064
}
1065
1066
impl Compare<AsciiCaseless<char>> for &str {
1067
    #[inline(always)]
1068
0
    fn compare(&self, t: AsciiCaseless<char>) -> CompareResult {
1069
0
        self.as_bytes().compare(t)
1070
0
    }
1071
}
1072
1073
/// Look for a slice in self
1074
pub trait FindSlice<T> {
1075
    /// Returns the offset of the slice if it is found
1076
    fn find_slice(&self, substr: T) -> Option<crate::lib::std::ops::Range<usize>>;
1077
}
1078
1079
impl<'s> FindSlice<&'s [u8]> for &[u8] {
1080
    #[inline(always)]
1081
0
    fn find_slice(&self, substr: &'s [u8]) -> Option<crate::lib::std::ops::Range<usize>> {
1082
0
        memmem(self, substr)
1083
0
    }
1084
}
1085
1086
impl<'s> FindSlice<(&'s [u8],)> for &[u8] {
1087
    #[inline(always)]
1088
0
    fn find_slice(&self, substr: (&'s [u8],)) -> Option<crate::lib::std::ops::Range<usize>> {
1089
0
        memmem(self, substr.0)
1090
0
    }
1091
}
1092
1093
impl<'s> FindSlice<(&'s [u8], &'s [u8])> for &[u8] {
1094
    #[inline(always)]
1095
0
    fn find_slice(
1096
0
        &self,
1097
0
        substr: (&'s [u8], &'s [u8]),
1098
0
    ) -> Option<crate::lib::std::ops::Range<usize>> {
1099
0
        memmem2(self, substr)
1100
0
    }
1101
}
1102
1103
impl<'s> FindSlice<(&'s [u8], &'s [u8], &'s [u8])> for &[u8] {
1104
    #[inline(always)]
1105
0
    fn find_slice(
1106
0
        &self,
1107
0
        substr: (&'s [u8], &'s [u8], &'s [u8]),
1108
0
    ) -> Option<crate::lib::std::ops::Range<usize>> {
1109
0
        memmem3(self, substr)
1110
0
    }
1111
}
1112
1113
impl FindSlice<char> for &[u8] {
1114
    #[inline(always)]
1115
0
    fn find_slice(&self, substr: char) -> Option<crate::lib::std::ops::Range<usize>> {
1116
0
        let mut b = [0; 4];
1117
0
        let substr = substr.encode_utf8(&mut b);
1118
0
        self.find_slice(&*substr)
1119
0
    }
1120
}
1121
1122
impl FindSlice<(char,)> for &[u8] {
1123
    #[inline(always)]
1124
0
    fn find_slice(&self, substr: (char,)) -> Option<crate::lib::std::ops::Range<usize>> {
1125
0
        let mut b = [0; 4];
1126
0
        let substr0 = substr.0.encode_utf8(&mut b);
1127
0
        self.find_slice((&*substr0,))
1128
0
    }
1129
}
1130
1131
impl FindSlice<(char, char)> for &[u8] {
1132
    #[inline(always)]
1133
0
    fn find_slice(&self, substr: (char, char)) -> Option<crate::lib::std::ops::Range<usize>> {
1134
0
        let mut b = [0; 4];
1135
0
        let substr0 = substr.0.encode_utf8(&mut b);
1136
0
        let mut b = [0; 4];
1137
0
        let substr1 = substr.1.encode_utf8(&mut b);
1138
0
        self.find_slice((&*substr0, &*substr1))
1139
0
    }
1140
}
1141
1142
impl FindSlice<(char, char, char)> for &[u8] {
1143
    #[inline(always)]
1144
0
    fn find_slice(&self, substr: (char, char, char)) -> Option<crate::lib::std::ops::Range<usize>> {
1145
0
        let mut b = [0; 4];
1146
0
        let substr0 = substr.0.encode_utf8(&mut b);
1147
0
        let mut b = [0; 4];
1148
0
        let substr1 = substr.1.encode_utf8(&mut b);
1149
0
        let mut b = [0; 4];
1150
0
        let substr2 = substr.2.encode_utf8(&mut b);
1151
0
        self.find_slice((&*substr0, &*substr1, &*substr2))
1152
0
    }
1153
}
1154
1155
impl FindSlice<u8> for &[u8] {
1156
    #[inline(always)]
1157
0
    fn find_slice(&self, substr: u8) -> Option<crate::lib::std::ops::Range<usize>> {
1158
0
        memchr(substr, self).map(|i| i..i + 1)
1159
0
    }
1160
}
1161
1162
impl FindSlice<(u8,)> for &[u8] {
1163
    #[inline(always)]
1164
0
    fn find_slice(&self, substr: (u8,)) -> Option<crate::lib::std::ops::Range<usize>> {
1165
0
        memchr(substr.0, self).map(|i| i..i + 1)
1166
0
    }
1167
}
1168
1169
impl FindSlice<(u8, u8)> for &[u8] {
1170
    #[inline(always)]
1171
0
    fn find_slice(&self, substr: (u8, u8)) -> Option<crate::lib::std::ops::Range<usize>> {
1172
0
        memchr2(substr, self).map(|i| i..i + 1)
1173
0
    }
1174
}
1175
1176
impl FindSlice<(u8, u8, u8)> for &[u8] {
1177
    #[inline(always)]
1178
0
    fn find_slice(&self, substr: (u8, u8, u8)) -> Option<crate::lib::std::ops::Range<usize>> {
1179
0
        memchr3(substr, self).map(|i| i..i + 1)
1180
0
    }
1181
}
1182
1183
impl<'s> FindSlice<&'s str> for &[u8] {
1184
    #[inline(always)]
1185
0
    fn find_slice(&self, substr: &'s str) -> Option<crate::lib::std::ops::Range<usize>> {
1186
0
        self.find_slice(substr.as_bytes())
1187
0
    }
1188
}
1189
1190
impl<'s> FindSlice<(&'s str,)> for &[u8] {
1191
    #[inline(always)]
1192
0
    fn find_slice(&self, substr: (&'s str,)) -> Option<crate::lib::std::ops::Range<usize>> {
1193
0
        memmem(self, substr.0.as_bytes())
1194
0
    }
1195
}
1196
1197
impl<'s> FindSlice<(&'s str, &'s str)> for &[u8] {
1198
    #[inline(always)]
1199
0
    fn find_slice(&self, substr: (&'s str, &'s str)) -> Option<crate::lib::std::ops::Range<usize>> {
1200
0
        memmem2(self, (substr.0.as_bytes(), substr.1.as_bytes()))
1201
0
    }
1202
}
1203
1204
impl<'s> FindSlice<(&'s str, &'s str, &'s str)> for &[u8] {
1205
    #[inline(always)]
1206
0
    fn find_slice(
1207
0
        &self,
1208
0
        substr: (&'s str, &'s str, &'s str),
1209
0
    ) -> Option<crate::lib::std::ops::Range<usize>> {
1210
0
        memmem3(
1211
0
            self,
1212
0
            (
1213
0
                substr.0.as_bytes(),
1214
0
                substr.1.as_bytes(),
1215
0
                substr.2.as_bytes(),
1216
0
            ),
1217
        )
1218
0
    }
1219
}
1220
1221
impl<'s> FindSlice<&'s str> for &str {
1222
    #[inline(always)]
1223
0
    fn find_slice(&self, substr: &'s str) -> Option<crate::lib::std::ops::Range<usize>> {
1224
0
        self.as_bytes().find_slice(substr)
1225
0
    }
1226
}
1227
1228
impl<'s> FindSlice<(&'s str,)> for &str {
1229
    #[inline(always)]
1230
0
    fn find_slice(&self, substr: (&'s str,)) -> Option<crate::lib::std::ops::Range<usize>> {
1231
0
        self.as_bytes().find_slice(substr)
1232
0
    }
1233
}
1234
1235
impl<'s> FindSlice<(&'s str, &'s str)> for &str {
1236
    #[inline(always)]
1237
0
    fn find_slice(&self, substr: (&'s str, &'s str)) -> Option<crate::lib::std::ops::Range<usize>> {
1238
0
        self.as_bytes().find_slice(substr)
1239
0
    }
1240
}
1241
1242
impl<'s> FindSlice<(&'s str, &'s str, &'s str)> for &str {
1243
    #[inline(always)]
1244
0
    fn find_slice(
1245
0
        &self,
1246
0
        substr: (&'s str, &'s str, &'s str),
1247
0
    ) -> Option<crate::lib::std::ops::Range<usize>> {
1248
0
        self.as_bytes().find_slice(substr)
1249
0
    }
1250
}
1251
1252
impl FindSlice<char> for &str {
1253
    #[inline(always)]
1254
0
    fn find_slice(&self, substr: char) -> Option<crate::lib::std::ops::Range<usize>> {
1255
0
        self.as_bytes().find_slice(substr)
1256
0
    }
1257
}
1258
1259
impl FindSlice<(char,)> for &str {
1260
    #[inline(always)]
1261
0
    fn find_slice(&self, substr: (char,)) -> Option<crate::lib::std::ops::Range<usize>> {
1262
0
        self.as_bytes().find_slice(substr)
1263
0
    }
1264
}
1265
1266
impl FindSlice<(char, char)> for &str {
1267
    #[inline(always)]
1268
0
    fn find_slice(&self, substr: (char, char)) -> Option<crate::lib::std::ops::Range<usize>> {
1269
0
        self.as_bytes().find_slice(substr)
1270
0
    }
1271
}
1272
1273
impl FindSlice<(char, char, char)> for &str {
1274
    #[inline(always)]
1275
0
    fn find_slice(&self, substr: (char, char, char)) -> Option<crate::lib::std::ops::Range<usize>> {
1276
0
        self.as_bytes().find_slice(substr)
1277
0
    }
1278
}
1279
1280
/// Used to integrate `str`'s `parse()` method
1281
pub trait ParseSlice<R> {
1282
    /// Succeeds if `parse()` succeeded
1283
    ///
1284
    /// The byte slice implementation will first convert it to a `&str`, then apply the `parse()`
1285
    /// function
1286
    fn parse_slice(&self) -> Option<R>;
1287
}
1288
1289
impl<R: FromStr> ParseSlice<R> for &[u8] {
1290
    #[inline(always)]
1291
0
    fn parse_slice(&self) -> Option<R> {
1292
0
        from_utf8(self).ok().and_then(|s| s.parse().ok())
1293
0
    }
1294
}
1295
1296
impl<R: FromStr> ParseSlice<R> for &str {
1297
    #[inline(always)]
1298
0
    fn parse_slice(&self) -> Option<R> {
1299
0
        self.parse().ok()
1300
0
    }
Unexecuted instantiation: <&str as winnow::stream::ParseSlice<duration_str::unit::TimeUnit>>::parse_slice
Unexecuted instantiation: <&str as winnow::stream::ParseSlice<_>>::parse_slice
1301
}
1302
1303
/// Convert a `Stream` into an appropriate `Output` type
1304
pub trait UpdateSlice: Stream {
1305
    /// Convert an `Output` type to be used as `Stream`
1306
    fn update_slice(self, inner: Self::Slice) -> Self;
1307
}
1308
1309
impl<T> UpdateSlice for &[T]
1310
where
1311
    T: Clone + crate::lib::std::fmt::Debug,
1312
{
1313
    #[inline(always)]
1314
0
    fn update_slice(self, inner: Self::Slice) -> Self {
1315
0
        inner
1316
0
    }
1317
}
1318
1319
impl UpdateSlice for &str {
1320
    #[inline(always)]
1321
0
    fn update_slice(self, inner: Self::Slice) -> Self {
1322
0
        inner
1323
0
    }
1324
}
1325
1326
/// Ensure checkpoint details are kept private
1327
pub struct Checkpoint<T, S> {
1328
    inner: T,
1329
    stream: core::marker::PhantomData<S>,
1330
}
1331
1332
impl<T, S> Checkpoint<T, S> {
1333
0
    fn new(inner: T) -> Self {
1334
0
        Self {
1335
0
            inner,
1336
0
            stream: Default::default(),
1337
0
        }
1338
0
    }
Unexecuted instantiation: <winnow::stream::Checkpoint<&str, &str>>::new
Unexecuted instantiation: <winnow::stream::Checkpoint<_, _>>::new
1339
}
1340
1341
impl<T: Copy, S> Copy for Checkpoint<T, S> {}
1342
1343
impl<T: Clone, S> Clone for Checkpoint<T, S> {
1344
    #[inline(always)]
1345
0
    fn clone(&self) -> Self {
1346
0
        Self {
1347
0
            inner: self.inner.clone(),
1348
0
            stream: Default::default(),
1349
0
        }
1350
0
    }
1351
}
1352
1353
impl<T: PartialOrd, S> PartialOrd for Checkpoint<T, S> {
1354
    #[inline(always)]
1355
0
    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1356
0
        self.inner.partial_cmp(&other.inner)
1357
0
    }
1358
}
1359
1360
impl<T: Ord, S> Ord for Checkpoint<T, S> {
1361
    #[inline(always)]
1362
0
    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1363
0
        self.inner.cmp(&other.inner)
1364
0
    }
1365
}
1366
1367
impl<T: PartialEq, S> PartialEq for Checkpoint<T, S> {
1368
    #[inline(always)]
1369
0
    fn eq(&self, other: &Self) -> bool {
1370
0
        self.inner.eq(&other.inner)
1371
0
    }
1372
}
1373
1374
impl<T: Eq, S> Eq for Checkpoint<T, S> {}
1375
1376
impl<T: crate::lib::std::fmt::Debug, S> crate::lib::std::fmt::Debug for Checkpoint<T, S> {
1377
0
    fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result {
1378
0
        self.inner.fmt(f)
1379
0
    }
1380
}
1381
1382
/// Abstracts something which can extend an `Extend`.
1383
/// Used to build modified input slices in `escaped_transform`
1384
pub trait Accumulate<T>: Sized {
1385
    /// Create a new `Extend` of the correct type
1386
    fn initial(capacity: Option<usize>) -> Self;
1387
    /// Accumulate the input into an accumulator
1388
    fn accumulate(&mut self, acc: T);
1389
}
1390
1391
impl<T> Accumulate<T> for () {
1392
    #[inline(always)]
1393
0
    fn initial(_capacity: Option<usize>) -> Self {}
1394
    #[inline(always)]
1395
0
    fn accumulate(&mut self, _acc: T) {}
1396
}
1397
1398
impl<T> Accumulate<T> for usize {
1399
    #[inline(always)]
1400
0
    fn initial(_capacity: Option<usize>) -> Self {
1401
0
        0
1402
0
    }
1403
    #[inline(always)]
1404
0
    fn accumulate(&mut self, _acc: T) {
1405
0
        *self += 1;
1406
0
    }
1407
}
1408
1409
#[cfg(feature = "alloc")]
1410
impl<T> Accumulate<T> for Vec<T> {
1411
    #[inline(always)]
1412
0
    fn initial(capacity: Option<usize>) -> Self {
1413
0
        match capacity {
1414
0
            Some(capacity) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
1415
0
            None => Vec::new(),
1416
        }
1417
0
    }
1418
    #[inline(always)]
1419
0
    fn accumulate(&mut self, acc: T) {
1420
0
        self.push(acc);
1421
0
    }
1422
}
1423
1424
#[cfg(feature = "alloc")]
1425
impl<'i, T: Clone> Accumulate<&'i [T]> for Vec<T> {
1426
    #[inline(always)]
1427
0
    fn initial(capacity: Option<usize>) -> Self {
1428
0
        match capacity {
1429
0
            Some(capacity) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
1430
0
            None => Vec::new(),
1431
        }
1432
0
    }
1433
    #[inline(always)]
1434
0
    fn accumulate(&mut self, acc: &'i [T]) {
1435
0
        self.extend(acc.iter().cloned());
1436
0
    }
1437
}
1438
1439
#[cfg(feature = "alloc")]
1440
impl Accumulate<char> for String {
1441
    #[inline(always)]
1442
0
    fn initial(capacity: Option<usize>) -> Self {
1443
0
        match capacity {
1444
0
            Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1445
0
            None => String::new(),
1446
        }
1447
0
    }
1448
    #[inline(always)]
1449
0
    fn accumulate(&mut self, acc: char) {
1450
0
        self.push(acc);
1451
0
    }
1452
}
1453
1454
#[cfg(feature = "alloc")]
1455
impl<'i> Accumulate<&'i str> for String {
1456
    #[inline(always)]
1457
0
    fn initial(capacity: Option<usize>) -> Self {
1458
0
        match capacity {
1459
0
            Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1460
0
            None => String::new(),
1461
        }
1462
0
    }
1463
    #[inline(always)]
1464
0
    fn accumulate(&mut self, acc: &'i str) {
1465
0
        self.push_str(acc);
1466
0
    }
1467
}
1468
1469
#[cfg(feature = "alloc")]
1470
impl<K, V> Accumulate<(K, V)> for BTreeMap<K, V>
1471
where
1472
    K: crate::lib::std::cmp::Ord,
1473
{
1474
    #[inline(always)]
1475
0
    fn initial(_capacity: Option<usize>) -> Self {
1476
0
        BTreeMap::new()
1477
0
    }
1478
    #[inline(always)]
1479
0
    fn accumulate(&mut self, (key, value): (K, V)) {
1480
0
        self.insert(key, value);
1481
0
    }
1482
}
1483
1484
#[cfg(feature = "std")]
1485
impl<K, V, S> Accumulate<(K, V)> for HashMap<K, V, S>
1486
where
1487
    K: crate::lib::std::cmp::Eq + crate::lib::std::hash::Hash,
1488
    S: BuildHasher + Default,
1489
{
1490
    #[inline(always)]
1491
0
    fn initial(capacity: Option<usize>) -> Self {
1492
0
        let h = S::default();
1493
0
        match capacity {
1494
0
            Some(capacity) => {
1495
0
                HashMap::with_capacity_and_hasher(clamp_capacity::<(K, V)>(capacity), h)
1496
            }
1497
0
            None => HashMap::with_hasher(h),
1498
        }
1499
0
    }
1500
    #[inline(always)]
1501
0
    fn accumulate(&mut self, (key, value): (K, V)) {
1502
0
        self.insert(key, value);
1503
0
    }
1504
}
1505
1506
#[cfg(feature = "alloc")]
1507
impl<K> Accumulate<K> for BTreeSet<K>
1508
where
1509
    K: crate::lib::std::cmp::Ord,
1510
{
1511
    #[inline(always)]
1512
0
    fn initial(_capacity: Option<usize>) -> Self {
1513
0
        BTreeSet::new()
1514
0
    }
1515
    #[inline(always)]
1516
0
    fn accumulate(&mut self, key: K) {
1517
0
        self.insert(key);
1518
0
    }
1519
}
1520
1521
#[cfg(feature = "std")]
1522
impl<K, S> Accumulate<K> for HashSet<K, S>
1523
where
1524
    K: crate::lib::std::cmp::Eq + crate::lib::std::hash::Hash,
1525
    S: BuildHasher + Default,
1526
{
1527
    #[inline(always)]
1528
0
    fn initial(capacity: Option<usize>) -> Self {
1529
0
        let h = S::default();
1530
0
        match capacity {
1531
0
            Some(capacity) => HashSet::with_capacity_and_hasher(clamp_capacity::<K>(capacity), h),
1532
0
            None => HashSet::with_hasher(h),
1533
        }
1534
0
    }
1535
    #[inline(always)]
1536
0
    fn accumulate(&mut self, key: K) {
1537
0
        self.insert(key);
1538
0
    }
1539
}
1540
1541
#[cfg(feature = "alloc")]
1542
#[inline]
1543
0
pub(crate) fn clamp_capacity<T>(capacity: usize) -> usize {
1544
    /// Don't pre-allocate more than 64KiB when calling `Vec::with_capacity`.
1545
    ///
1546
    /// Pre-allocating memory is a nice optimization but count fields can't
1547
    /// always be trusted. We should clamp initial capacities to some reasonable
1548
    /// amount. This reduces the risk of a bogus count value triggering a panic
1549
    /// due to an OOM error.
1550
    ///
1551
    /// This does not affect correctness. `winnow` will always read the full number
1552
    /// of elements regardless of the capacity cap.
1553
    const MAX_INITIAL_CAPACITY_BYTES: usize = 65536;
1554
1555
0
    let max_initial_capacity =
1556
0
        MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::<T>().max(1);
1557
0
    capacity.min(max_initial_capacity)
1558
0
}
1559
1560
/// Helper trait to convert numbers to usize.
1561
///
1562
/// By default, usize implements `From<u8>` and `From<u16>` but not
1563
/// `From<u32>` and `From<u64>` because that would be invalid on some
1564
/// platforms. This trait implements the conversion for platforms
1565
/// with 32 and 64 bits pointer platforms
1566
pub trait ToUsize {
1567
    /// converts self to usize
1568
    fn to_usize(&self) -> usize;
1569
}
1570
1571
impl ToUsize for u8 {
1572
    #[inline(always)]
1573
0
    fn to_usize(&self) -> usize {
1574
0
        *self as usize
1575
0
    }
1576
}
1577
1578
impl ToUsize for u16 {
1579
    #[inline(always)]
1580
0
    fn to_usize(&self) -> usize {
1581
0
        *self as usize
1582
0
    }
1583
}
1584
1585
impl ToUsize for usize {
1586
    #[inline(always)]
1587
0
    fn to_usize(&self) -> usize {
1588
0
        *self
1589
0
    }
1590
}
1591
1592
#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
1593
impl ToUsize for u32 {
1594
    #[inline(always)]
1595
0
    fn to_usize(&self) -> usize {
1596
0
        *self as usize
1597
0
    }
1598
}
1599
1600
#[cfg(target_pointer_width = "64")]
1601
impl ToUsize for u64 {
1602
    #[inline(always)]
1603
0
    fn to_usize(&self) -> usize {
1604
0
        *self as usize
1605
0
    }
1606
}
1607
1608
/// Transforms a token into a char for basic string parsing
1609
#[allow(clippy::len_without_is_empty)]
1610
#[allow(clippy::wrong_self_convention)]
1611
pub trait AsChar {
1612
    /// Makes a char from self
1613
    ///
1614
    /// # Example
1615
    ///
1616
    /// ```
1617
    /// use winnow::prelude::*;
1618
    ///
1619
    /// assert_eq!('a'.as_char(), 'a');
1620
    /// assert_eq!(u8::MAX.as_char(), std::char::from_u32(u8::MAX as u32).unwrap());
1621
    /// ```
1622
    fn as_char(self) -> char;
1623
1624
    /// Tests that self is an alphabetic character
1625
    ///
1626
    /// <div class="warning">
1627
    ///
1628
    /// **Warning:** for `&str` it matches alphabetic
1629
    /// characters outside of the 52 ASCII letters
1630
    ///
1631
    /// </div>
1632
    fn is_alpha(self) -> bool;
1633
1634
    /// Tests that self is an alphabetic character
1635
    /// or a decimal digit
1636
    fn is_alphanum(self) -> bool;
1637
    /// Tests that self is a decimal digit
1638
    fn is_dec_digit(self) -> bool;
1639
    /// Tests that self is an hex digit
1640
    fn is_hex_digit(self) -> bool;
1641
    /// Tests that self is an octal digit
1642
    fn is_oct_digit(self) -> bool;
1643
    /// Gets the len in bytes for self
1644
    fn len(self) -> usize;
1645
    /// Tests that self is ASCII space or tab
1646
    fn is_space(self) -> bool;
1647
    /// Tests if byte is ASCII newline: \n
1648
    fn is_newline(self) -> bool;
1649
}
1650
1651
impl AsChar for u8 {
1652
    #[inline(always)]
1653
0
    fn as_char(self) -> char {
1654
0
        self as char
1655
0
    }
1656
    #[inline]
1657
0
    fn is_alpha(self) -> bool {
1658
0
        matches!(self, 0x41..=0x5A | 0x61..=0x7A)
1659
0
    }
1660
    #[inline]
1661
0
    fn is_alphanum(self) -> bool {
1662
0
        self.is_alpha() || self.is_dec_digit()
1663
0
    }
1664
    #[inline]
1665
0
    fn is_dec_digit(self) -> bool {
1666
0
        matches!(self, 0x30..=0x39)
1667
0
    }
1668
    #[inline]
1669
0
    fn is_hex_digit(self) -> bool {
1670
0
        matches!(self, 0x30..=0x39 | 0x41..=0x46 | 0x61..=0x66)
1671
0
    }
1672
    #[inline]
1673
0
    fn is_oct_digit(self) -> bool {
1674
0
        matches!(self, 0x30..=0x37)
1675
0
    }
1676
    #[inline]
1677
0
    fn len(self) -> usize {
1678
0
        1
1679
0
    }
1680
    #[inline]
1681
0
    fn is_space(self) -> bool {
1682
0
        self == b' ' || self == b'\t'
1683
0
    }
1684
    #[inline]
1685
0
    fn is_newline(self) -> bool {
1686
0
        self == b'\n'
1687
0
    }
1688
}
1689
1690
impl AsChar for &u8 {
1691
    #[inline(always)]
1692
0
    fn as_char(self) -> char {
1693
0
        (*self).as_char()
1694
0
    }
1695
    #[inline(always)]
1696
0
    fn is_alpha(self) -> bool {
1697
0
        (*self).is_alpha()
1698
0
    }
1699
    #[inline(always)]
1700
0
    fn is_alphanum(self) -> bool {
1701
0
        (*self).is_alphanum()
1702
0
    }
1703
    #[inline(always)]
1704
0
    fn is_dec_digit(self) -> bool {
1705
0
        (*self).is_dec_digit()
1706
0
    }
1707
    #[inline(always)]
1708
0
    fn is_hex_digit(self) -> bool {
1709
0
        (*self).is_hex_digit()
1710
0
    }
1711
    #[inline(always)]
1712
0
    fn is_oct_digit(self) -> bool {
1713
0
        (*self).is_oct_digit()
1714
0
    }
1715
    #[inline(always)]
1716
0
    fn len(self) -> usize {
1717
0
        (*self).len()
1718
0
    }
1719
    #[inline(always)]
1720
0
    fn is_space(self) -> bool {
1721
0
        (*self).is_space()
1722
0
    }
1723
    #[inline(always)]
1724
0
    fn is_newline(self) -> bool {
1725
0
        (*self).is_newline()
1726
0
    }
1727
}
1728
1729
impl AsChar for char {
1730
    #[inline(always)]
1731
0
    fn as_char(self) -> char {
1732
0
        self
1733
0
    }
1734
    #[inline]
1735
0
    fn is_alpha(self) -> bool {
1736
0
        self.is_ascii_alphabetic()
1737
0
    }
Unexecuted instantiation: <char as winnow::stream::AsChar>::is_alpha
Unexecuted instantiation: <char as winnow::stream::AsChar>::is_alpha
1738
    #[inline]
1739
0
    fn is_alphanum(self) -> bool {
1740
0
        self.is_alpha() || self.is_dec_digit()
1741
0
    }
1742
    #[inline]
1743
0
    fn is_dec_digit(self) -> bool {
1744
0
        self.is_ascii_digit()
1745
0
    }
Unexecuted instantiation: <char as winnow::stream::AsChar>::is_dec_digit
Unexecuted instantiation: <char as winnow::stream::AsChar>::is_dec_digit
1746
    #[inline]
1747
0
    fn is_hex_digit(self) -> bool {
1748
0
        self.is_ascii_hexdigit()
1749
0
    }
1750
    #[inline]
1751
0
    fn is_oct_digit(self) -> bool {
1752
0
        self.is_digit(8)
1753
0
    }
1754
    #[inline]
1755
0
    fn len(self) -> usize {
1756
0
        self.len_utf8()
1757
0
    }
Unexecuted instantiation: <char as winnow::stream::AsChar>::len
Unexecuted instantiation: <char as winnow::stream::AsChar>::len
1758
    #[inline]
1759
0
    fn is_space(self) -> bool {
1760
0
        self == ' ' || self == '\t'
1761
0
    }
1762
    #[inline]
1763
0
    fn is_newline(self) -> bool {
1764
0
        self == '\n'
1765
0
    }
1766
}
1767
1768
impl AsChar for &char {
1769
    #[inline(always)]
1770
0
    fn as_char(self) -> char {
1771
0
        (*self).as_char()
1772
0
    }
1773
    #[inline(always)]
1774
0
    fn is_alpha(self) -> bool {
1775
0
        (*self).is_alpha()
1776
0
    }
1777
    #[inline(always)]
1778
0
    fn is_alphanum(self) -> bool {
1779
0
        (*self).is_alphanum()
1780
0
    }
1781
    #[inline(always)]
1782
0
    fn is_dec_digit(self) -> bool {
1783
0
        (*self).is_dec_digit()
1784
0
    }
1785
    #[inline(always)]
1786
0
    fn is_hex_digit(self) -> bool {
1787
0
        (*self).is_hex_digit()
1788
0
    }
1789
    #[inline(always)]
1790
0
    fn is_oct_digit(self) -> bool {
1791
0
        (*self).is_oct_digit()
1792
0
    }
1793
    #[inline(always)]
1794
0
    fn len(self) -> usize {
1795
0
        (*self).len()
1796
0
    }
1797
    #[inline(always)]
1798
0
    fn is_space(self) -> bool {
1799
0
        (*self).is_space()
1800
0
    }
1801
    #[inline(always)]
1802
0
    fn is_newline(self) -> bool {
1803
0
        (*self).is_newline()
1804
0
    }
1805
}
1806
1807
/// Check if a token is in a set of possible tokens
1808
///
1809
/// While this can be implemented manually, you can also build up sets using:
1810
/// - `b'c'` and `'c'`
1811
/// - `b""`
1812
/// - `|c| true`
1813
/// - `b'a'..=b'z'`, `'a'..='z'` (etc for each [range type][std::ops])
1814
/// - `(set1, set2, ...)`
1815
///
1816
/// # Example
1817
///
1818
/// For example, you could implement `hex_digit0` as:
1819
/// ```
1820
/// # use winnow::prelude::*;
1821
/// # use winnow::{error::ErrMode, error::ContextError};
1822
/// # use winnow::token::take_while;
1823
/// fn hex_digit1<'s>(input: &mut &'s str) -> ModalResult<&'s str, ContextError> {
1824
///     take_while(1.., ('a'..='f', 'A'..='F', '0'..='9')).parse_next(input)
1825
/// }
1826
///
1827
/// assert_eq!(hex_digit1.parse_peek("21cZ"), Ok(("Z", "21c")));
1828
/// assert!(hex_digit1.parse_peek("H2").is_err());
1829
/// assert!(hex_digit1.parse_peek("").is_err());
1830
/// ```
1831
pub trait ContainsToken<T> {
1832
    /// Returns true if self contains the token
1833
    fn contains_token(&self, token: T) -> bool;
1834
}
1835
1836
impl ContainsToken<u8> for u8 {
1837
    #[inline(always)]
1838
0
    fn contains_token(&self, token: u8) -> bool {
1839
0
        *self == token
1840
0
    }
1841
}
1842
1843
impl ContainsToken<&u8> for u8 {
1844
    #[inline(always)]
1845
0
    fn contains_token(&self, token: &u8) -> bool {
1846
0
        self.contains_token(*token)
1847
0
    }
1848
}
1849
1850
impl ContainsToken<char> for u8 {
1851
    #[inline(always)]
1852
0
    fn contains_token(&self, token: char) -> bool {
1853
0
        self.as_char() == token
1854
0
    }
1855
}
1856
1857
impl ContainsToken<&char> for u8 {
1858
    #[inline(always)]
1859
0
    fn contains_token(&self, token: &char) -> bool {
1860
0
        self.contains_token(*token)
1861
0
    }
1862
}
1863
1864
impl<C: AsChar> ContainsToken<C> for char {
1865
    #[inline(always)]
1866
0
    fn contains_token(&self, token: C) -> bool {
1867
0
        *self == token.as_char()
1868
0
    }
Unexecuted instantiation: <char as winnow::stream::ContainsToken<char>>::contains_token
Unexecuted instantiation: <char as winnow::stream::ContainsToken<_>>::contains_token
1869
}
1870
1871
impl<C, F: Fn(C) -> bool> ContainsToken<C> for F {
1872
    #[inline(always)]
1873
0
    fn contains_token(&self, token: C) -> bool {
1874
0
        self(token)
1875
0
    }
Unexecuted instantiation: <duration_str::unit::unit_abbr1::{closure#0} as winnow::stream::ContainsToken<char>>::contains_token
Unexecuted instantiation: <<duration_str::CondUnit>::contain as winnow::stream::ContainsToken<char>>::contains_token
Unexecuted instantiation: <<char as winnow::stream::AsChar>::is_dec_digit as winnow::stream::ContainsToken<char>>::contains_token
Unexecuted instantiation: <_ as winnow::stream::ContainsToken<_>>::contains_token
1876
}
1877
1878
impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::Range<C2> {
1879
    #[inline(always)]
1880
0
    fn contains_token(&self, token: C1) -> bool {
1881
0
        let start = self.start.clone().as_char();
1882
0
        let end = self.end.clone().as_char();
1883
0
        (start..end).contains(&token.as_char())
1884
0
    }
1885
}
1886
1887
impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1>
1888
    for crate::lib::std::ops::RangeInclusive<C2>
1889
{
1890
    #[inline(always)]
1891
0
    fn contains_token(&self, token: C1) -> bool {
1892
0
        let start = self.start().clone().as_char();
1893
0
        let end = self.end().clone().as_char();
1894
0
        (start..=end).contains(&token.as_char())
1895
0
    }
1896
}
1897
1898
impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::RangeFrom<C2> {
1899
    #[inline(always)]
1900
0
    fn contains_token(&self, token: C1) -> bool {
1901
0
        let start = self.start.clone().as_char();
1902
0
        (start..).contains(&token.as_char())
1903
0
    }
1904
}
1905
1906
impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::RangeTo<C2> {
1907
    #[inline(always)]
1908
0
    fn contains_token(&self, token: C1) -> bool {
1909
0
        let end = self.end.clone().as_char();
1910
0
        (..end).contains(&token.as_char())
1911
0
    }
1912
}
1913
1914
impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1>
1915
    for crate::lib::std::ops::RangeToInclusive<C2>
1916
{
1917
    #[inline(always)]
1918
0
    fn contains_token(&self, token: C1) -> bool {
1919
0
        let end = self.end.clone().as_char();
1920
0
        (..=end).contains(&token.as_char())
1921
0
    }
1922
}
1923
1924
impl<C1: AsChar> ContainsToken<C1> for crate::lib::std::ops::RangeFull {
1925
    #[inline(always)]
1926
0
    fn contains_token(&self, _token: C1) -> bool {
1927
0
        true
1928
0
    }
1929
}
1930
1931
impl<C: AsChar> ContainsToken<C> for &'_ [u8] {
1932
    #[inline]
1933
0
    fn contains_token(&self, token: C) -> bool {
1934
0
        let token = token.as_char();
1935
0
        self.iter().any(|t| t.as_char() == token)
1936
0
    }
1937
}
1938
1939
impl<C: AsChar> ContainsToken<C> for &'_ [char] {
1940
    #[inline]
1941
0
    fn contains_token(&self, token: C) -> bool {
1942
0
        let token = token.as_char();
1943
0
        self.iter().any(|t| *t == token)
1944
0
    }
1945
}
1946
1947
impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [u8; LEN] {
1948
    #[inline]
1949
0
    fn contains_token(&self, token: C) -> bool {
1950
0
        let token = token.as_char();
1951
0
        self.iter().any(|t| t.as_char() == token)
1952
0
    }
1953
}
1954
1955
impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [char; LEN] {
1956
    #[inline]
1957
0
    fn contains_token(&self, token: C) -> bool {
1958
0
        let token = token.as_char();
1959
0
        self.iter().any(|t| *t == token)
1960
0
    }
1961
}
1962
1963
impl<const LEN: usize, C: AsChar> ContainsToken<C> for [u8; LEN] {
1964
    #[inline]
1965
0
    fn contains_token(&self, token: C) -> bool {
1966
0
        let token = token.as_char();
1967
0
        self.iter().any(|t| t.as_char() == token)
1968
0
    }
1969
}
1970
1971
impl<const LEN: usize, C: AsChar> ContainsToken<C> for [char; LEN] {
1972
    #[inline]
1973
0
    fn contains_token(&self, token: C) -> bool {
1974
0
        let token = token.as_char();
1975
0
        self.iter().any(|t| *t == token)
1976
0
    }
1977
}
1978
1979
impl<T> ContainsToken<T> for () {
1980
    #[inline(always)]
1981
0
    fn contains_token(&self, _token: T) -> bool {
1982
0
        false
1983
0
    }
1984
}
1985
1986
macro_rules! impl_contains_token_for_tuple {
1987
  ($($haystack:ident),+) => (
1988
    #[allow(non_snake_case)]
1989
    impl<T, $($haystack),+> ContainsToken<T> for ($($haystack),+,)
1990
    where
1991
    T: Clone,
1992
      $($haystack: ContainsToken<T>),+
1993
    {
1994
    #[inline]
1995
0
      fn contains_token(&self, token: T) -> bool {
1996
0
        let ($(ref $haystack),+,) = *self;
1997
0
        $($haystack.contains_token(token.clone()) || )+ false
1998
0
      }
Unexecuted instantiation: <(char, char, char, char) as winnow::stream::ContainsToken<char>>::contains_token
Unexecuted instantiation: <(_,) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
Unexecuted instantiation: <(_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) as winnow::stream::ContainsToken<_>>::contains_token
1999
    }
2000
  )
2001
}
2002
2003
macro_rules! impl_contains_token_for_tuples {
2004
    ($haystack1:ident, $($haystack:ident),+) => {
2005
        impl_contains_token_for_tuples!(__impl $haystack1; $($haystack),+);
2006
    };
2007
    (__impl $($haystack:ident),+; $haystack1:ident $(,$haystack2:ident)*) => {
2008
        impl_contains_token_for_tuple!($($haystack),+);
2009
        impl_contains_token_for_tuples!(__impl $($haystack),+, $haystack1; $($haystack2),*);
2010
    };
2011
    (__impl $($haystack:ident),+;) => {
2012
        impl_contains_token_for_tuple!($($haystack),+);
2013
    }
2014
}
2015
2016
impl_contains_token_for_tuples!(
2017
    F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21
2018
);
2019
2020
#[cfg(feature = "simd")]
2021
#[inline(always)]
2022
fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
2023
    memchr::memchr(token, slice)
2024
}
2025
2026
#[cfg(feature = "simd")]
2027
#[inline(always)]
2028
fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
2029
    memchr::memchr2(token.0, token.1, slice)
2030
}
2031
2032
#[cfg(feature = "simd")]
2033
#[inline(always)]
2034
fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
2035
    memchr::memchr3(token.0, token.1, token.2, slice)
2036
}
2037
2038
#[cfg(not(feature = "simd"))]
2039
#[inline(always)]
2040
0
fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
2041
0
    slice.iter().position(|t| *t == token)
2042
0
}
2043
2044
#[cfg(not(feature = "simd"))]
2045
#[inline(always)]
2046
0
fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
2047
0
    slice.iter().position(|t| *t == token.0 || *t == token.1)
2048
0
}
2049
2050
#[cfg(not(feature = "simd"))]
2051
#[inline(always)]
2052
0
fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
2053
0
    slice
2054
0
        .iter()
2055
0
        .position(|t| *t == token.0 || *t == token.1 || *t == token.2)
2056
0
}
2057
2058
#[inline(always)]
2059
0
fn memmem(slice: &[u8], literal: &[u8]) -> Option<crate::lib::std::ops::Range<usize>> {
2060
0
    match literal.len() {
2061
0
        0 => Some(0..0),
2062
0
        1 => memchr(literal[0], slice).map(|i| i..i + 1),
2063
0
        _ => memmem_(slice, literal),
2064
    }
2065
0
}
2066
2067
#[inline(always)]
2068
0
fn memmem2(slice: &[u8], literal: (&[u8], &[u8])) -> Option<crate::lib::std::ops::Range<usize>> {
2069
0
    match (literal.0.len(), literal.1.len()) {
2070
0
        (0, _) | (_, 0) => Some(0..0),
2071
0
        (1, 1) => memchr2((literal.0[0], literal.1[0]), slice).map(|i| i..i + 1),
2072
0
        _ => memmem2_(slice, literal),
2073
    }
2074
0
}
2075
2076
#[inline(always)]
2077
0
fn memmem3(
2078
0
    slice: &[u8],
2079
0
    literal: (&[u8], &[u8], &[u8]),
2080
0
) -> Option<crate::lib::std::ops::Range<usize>> {
2081
0
    match (literal.0.len(), literal.1.len(), literal.2.len()) {
2082
0
        (0, _, _) | (_, 0, _) | (_, _, 0) => Some(0..0),
2083
0
        (1, 1, 1) => memchr3((literal.0[0], literal.1[0], literal.2[0]), slice).map(|i| i..i + 1),
2084
0
        _ => memmem3_(slice, literal),
2085
    }
2086
0
}
2087
2088
#[cfg(feature = "simd")]
2089
#[inline(always)]
2090
fn memmem_(slice: &[u8], literal: &[u8]) -> Option<crate::lib::std::ops::Range<usize>> {
2091
    let &prefix = match literal.first() {
2092
        Some(x) => x,
2093
        None => return Some(0..0),
2094
    };
2095
    #[allow(clippy::manual_find)] // faster this way
2096
    for i in memchr::memchr_iter(prefix, slice) {
2097
        if slice[i..].starts_with(literal) {
2098
            let i_end = i + literal.len();
2099
            return Some(i..i_end);
2100
        }
2101
    }
2102
    None
2103
}
2104
2105
#[cfg(feature = "simd")]
2106
fn memmem2_(slice: &[u8], literal: (&[u8], &[u8])) -> Option<crate::lib::std::ops::Range<usize>> {
2107
    let prefix = match (literal.0.first(), literal.1.first()) {
2108
        (Some(&a), Some(&b)) => (a, b),
2109
        _ => return Some(0..0),
2110
    };
2111
    #[allow(clippy::manual_find)] // faster this way
2112
    for i in memchr::memchr2_iter(prefix.0, prefix.1, slice) {
2113
        let subslice = &slice[i..];
2114
        if subslice.starts_with(literal.0) {
2115
            let i_end = i + literal.0.len();
2116
            return Some(i..i_end);
2117
        }
2118
        if subslice.starts_with(literal.1) {
2119
            let i_end = i + literal.1.len();
2120
            return Some(i..i_end);
2121
        }
2122
    }
2123
    None
2124
}
2125
2126
#[cfg(feature = "simd")]
2127
fn memmem3_(
2128
    slice: &[u8],
2129
    literal: (&[u8], &[u8], &[u8]),
2130
) -> Option<crate::lib::std::ops::Range<usize>> {
2131
    let prefix = match (literal.0.first(), literal.1.first(), literal.2.first()) {
2132
        (Some(&a), Some(&b), Some(&c)) => (a, b, c),
2133
        _ => return Some(0..0),
2134
    };
2135
    #[allow(clippy::manual_find)] // faster this way
2136
    for i in memchr::memchr3_iter(prefix.0, prefix.1, prefix.2, slice) {
2137
        let subslice = &slice[i..];
2138
        if subslice.starts_with(literal.0) {
2139
            let i_end = i + literal.0.len();
2140
            return Some(i..i_end);
2141
        }
2142
        if subslice.starts_with(literal.1) {
2143
            let i_end = i + literal.1.len();
2144
            return Some(i..i_end);
2145
        }
2146
        if subslice.starts_with(literal.2) {
2147
            let i_end = i + literal.2.len();
2148
            return Some(i..i_end);
2149
        }
2150
    }
2151
    None
2152
}
2153
2154
#[cfg(not(feature = "simd"))]
2155
0
fn memmem_(slice: &[u8], literal: &[u8]) -> Option<crate::lib::std::ops::Range<usize>> {
2156
0
    for i in 0..slice.len() {
2157
0
        let subslice = &slice[i..];
2158
0
        if subslice.starts_with(literal) {
2159
0
            let i_end = i + literal.len();
2160
0
            return Some(i..i_end);
2161
0
        }
2162
    }
2163
0
    None
2164
0
}
2165
2166
#[cfg(not(feature = "simd"))]
2167
0
fn memmem2_(slice: &[u8], literal: (&[u8], &[u8])) -> Option<crate::lib::std::ops::Range<usize>> {
2168
0
    for i in 0..slice.len() {
2169
0
        let subslice = &slice[i..];
2170
0
        if subslice.starts_with(literal.0) {
2171
0
            let i_end = i + literal.0.len();
2172
0
            return Some(i..i_end);
2173
0
        }
2174
0
        if subslice.starts_with(literal.1) {
2175
0
            let i_end = i + literal.1.len();
2176
0
            return Some(i..i_end);
2177
0
        }
2178
    }
2179
0
    None
2180
0
}
2181
2182
#[cfg(not(feature = "simd"))]
2183
0
fn memmem3_(
2184
0
    slice: &[u8],
2185
0
    literal: (&[u8], &[u8], &[u8]),
2186
0
) -> Option<crate::lib::std::ops::Range<usize>> {
2187
0
    for i in 0..slice.len() {
2188
0
        let subslice = &slice[i..];
2189
0
        if subslice.starts_with(literal.0) {
2190
0
            let i_end = i + literal.0.len();
2191
0
            return Some(i..i_end);
2192
0
        }
2193
0
        if subslice.starts_with(literal.1) {
2194
0
            let i_end = i + literal.1.len();
2195
0
            return Some(i..i_end);
2196
0
        }
2197
0
        if subslice.starts_with(literal.2) {
2198
0
            let i_end = i + literal.2.len();
2199
0
            return Some(i..i_end);
2200
0
        }
2201
    }
2202
0
    None
2203
0
}