winnow/stream/
mod.rs

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
12use core::hash::BuildHasher;
13use core::num::NonZeroUsize;
14
15use crate::ascii::Caseless as AsciiCaseless;
16use crate::error::Needed;
17use crate::lib::std::iter::{Cloned, Enumerate};
18use crate::lib::std::slice::Iter;
19use crate::lib::std::str::from_utf8;
20use crate::lib::std::str::CharIndices;
21use crate::lib::std::str::FromStr;
22
23#[allow(unused_imports)]
24#[cfg(any(feature = "unstable-doc", feature = "unstable-recover"))]
25use crate::error::ErrMode;
26
27#[cfg(feature = "alloc")]
28use crate::lib::std::collections::BTreeMap;
29#[cfg(feature = "alloc")]
30use crate::lib::std::collections::BTreeSet;
31#[cfg(feature = "std")]
32use crate::lib::std::collections::HashMap;
33#[cfg(feature = "std")]
34use crate::lib::std::collections::HashSet;
35#[cfg(feature = "alloc")]
36use crate::lib::std::string::String;
37#[cfg(feature = "alloc")]
38use crate::lib::std::vec::Vec;
39
40mod bstr;
41mod bytes;
42mod locating;
43mod partial;
44mod range;
45#[cfg(feature = "unstable-recover")]
46#[cfg(feature = "std")]
47mod recoverable;
48mod stateful;
49#[cfg(test)]
50mod tests;
51mod token;
52
53pub use bstr::BStr;
54pub use bytes::Bytes;
55pub use locating::LocatingSlice;
56pub use partial::Partial;
57pub use range::Range;
58#[cfg(feature = "unstable-recover")]
59#[cfg(feature = "std")]
60pub use recoverable::Recoverable;
61pub use stateful::Stateful;
62pub use token::TokenSlice;
63
64/// UTF-8 Stream
65pub type Str<'i> = &'i str;
66
67/// Abstract method to calculate the input length
68pub 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
74impl<S: SliceLen> SliceLen for AsciiCaseless<S> {
75    #[inline(always)]
76    fn slice_len(&self) -> usize {
77        self.0.slice_len()
78    }
79}
80
81impl<T> SliceLen for &[T] {
82    #[inline(always)]
83    fn slice_len(&self) -> usize {
84        self.len()
85    }
86}
87
88impl<T, const LEN: usize> SliceLen for [T; LEN] {
89    #[inline(always)]
90    fn slice_len(&self) -> usize {
91        self.len()
92    }
93}
94
95impl<T, const LEN: usize> SliceLen for &[T; LEN] {
96    #[inline(always)]
97    fn slice_len(&self) -> usize {
98        self.len()
99    }
100}
101
102impl SliceLen for &str {
103    #[inline(always)]
104    fn slice_len(&self) -> usize {
105        self.len()
106    }
107}
108
109impl SliceLen for u8 {
110    #[inline(always)]
111    fn slice_len(&self) -> usize {
112        1
113    }
114}
115
116impl SliceLen for char {
117    #[inline(always)]
118    fn slice_len(&self) -> usize {
119        self.len_utf8()
120    }
121}
122
123impl<I> SliceLen for (I, usize, usize)
124where
125    I: SliceLen,
126{
127    #[inline(always)]
128    fn slice_len(&self) -> usize {
129        self.0.slice_len() * 8 + self.2 - self.1
130    }
131}
132
133/// Core definition for parser input state
134pub 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    unsafe fn next_slice_unchecked(&mut self, offset: usize) -> Self::Slice {
213        // Inherent impl to allow callers to have `unsafe`-free code
214        self.next_slice(offset)
215    }
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    unsafe fn peek_slice_unchecked(&self, offset: usize) -> Self::Slice {
228        // Inherent impl to allow callers to have `unsafe`-free code
229        self.peek_slice(offset)
230    }
231
232    /// Advance to the end of the stream
233    #[inline(always)]
234    fn finish(&mut self) -> Self::Slice {
235        self.next_slice(self.eof_offset())
236    }
237    /// Advance to the end of the stream
238    #[inline(always)]
239    fn peek_finish(&self) -> Self::Slice
240    where
241        Self: Clone,
242    {
243        self.peek_slice(self.eof_offset())
244    }
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
259impl<'i, T> Stream for &'i [T]
260where
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    fn iter_offsets(&self) -> Self::IterOffsets {
272        self.iter().cloned().enumerate()
273    }
274    #[inline(always)]
275    fn eof_offset(&self) -> usize {
276        self.len()
277    }
278
279    #[inline(always)]
280    fn next_token(&mut self) -> Option<Self::Token> {
281        let (token, next) = self.split_first()?;
282        *self = next;
283        Some(token.clone())
284    }
285
286    #[inline(always)]
287    fn peek_token(&self) -> Option<Self::Token> {
288        if self.is_empty() {
289            None
290        } else {
291            Some(self[0].clone())
292        }
293    }
294
295    #[inline(always)]
296    fn offset_for<P>(&self, predicate: P) -> Option<usize>
297    where
298        P: Fn(Self::Token) -> bool,
299    {
300        self.iter().position(|b| predicate(b.clone()))
301    }
302    #[inline(always)]
303    fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
304        if let Some(needed) = tokens.checked_sub(self.len()).and_then(NonZeroUsize::new) {
305            Err(Needed::Size(needed))
306        } else {
307            Ok(tokens)
308        }
309    }
310    #[inline(always)]
311    fn next_slice(&mut self, offset: usize) -> Self::Slice {
312        let (slice, next) = self.split_at(offset);
313        *self = next;
314        slice
315    }
316    #[inline(always)]
317    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        let slice = unsafe { self.get_unchecked(..offset) };
323        // SAFETY: `Stream::next_slice_unchecked` requires `offset` to be in bounds
324        let next = unsafe { self.get_unchecked(offset..) };
325        *self = next;
326        slice
327    }
328    #[inline(always)]
329    fn peek_slice(&self, offset: usize) -> Self::Slice {
330        &self[..offset]
331    }
332    #[inline(always)]
333    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        let slice = unsafe { self.get_unchecked(..offset) };
339        slice
340    }
341
342    #[inline(always)]
343    fn checkpoint(&self) -> Self::Checkpoint {
344        Checkpoint::<_, Self>::new(*self)
345    }
346    #[inline(always)]
347    fn reset(&mut self, checkpoint: &Self::Checkpoint) {
348        *self = checkpoint.inner;
349    }
350
351    #[inline(always)]
352    fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
353        self
354    }
355}
356
357impl<'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    fn iter_offsets(&self) -> Self::IterOffsets {
367        self.char_indices()
368    }
369    #[inline(always)]
370    fn eof_offset(&self) -> usize {
371        self.len()
372    }
373
374    #[inline(always)]
375    fn next_token(&mut self) -> Option<Self::Token> {
376        let c = self.chars().next()?;
377        let offset = c.len();
378        *self = &self[offset..];
379        Some(c)
380    }
381
382    #[inline(always)]
383    fn peek_token(&self) -> Option<Self::Token> {
384        self.chars().next()
385    }
386
387    #[inline(always)]
388    fn offset_for<P>(&self, predicate: P) -> Option<usize>
389    where
390        P: Fn(Self::Token) -> bool,
391    {
392        for (o, c) in self.iter_offsets() {
393            if predicate(c) {
394                return Some(o);
395            }
396        }
397        None
398    }
399    #[inline]
400    fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
401        let mut cnt = 0;
402        for (offset, _) in self.iter_offsets() {
403            if cnt == tokens {
404                return Ok(offset);
405            }
406            cnt += 1;
407        }
408
409        if cnt == tokens {
410            Ok(self.eof_offset())
411        } else {
412            Err(Needed::Unknown)
413        }
414    }
415    #[inline(always)]
416    fn next_slice(&mut self, offset: usize) -> Self::Slice {
417        let (slice, next) = self.split_at(offset);
418        *self = next;
419        slice
420    }
421    #[inline(always)]
422    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        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        let next = unsafe { self.get_unchecked(offset..) };
432        *self = next;
433        slice
434    }
435    #[inline(always)]
436    fn peek_slice(&self, offset: usize) -> Self::Slice {
437        &self[..offset]
438    }
439    #[inline(always)]
440    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        let slice = unsafe { self.get_unchecked(..offset) };
446        slice
447    }
448
449    #[inline(always)]
450    fn checkpoint(&self) -> Self::Checkpoint {
451        Checkpoint::<_, Self>::new(*self)
452    }
453    #[inline(always)]
454    fn reset(&mut self, checkpoint: &Self::Checkpoint) {
455        *self = checkpoint.inner;
456    }
457
458    #[inline(always)]
459    fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
460        self
461    }
462}
463
464impl<I> Stream for (I, usize)
465where
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    fn iter_offsets(&self) -> Self::IterOffsets {
477        BitOffsets {
478            i: self.clone(),
479            o: 0,
480        }
481    }
482    #[inline(always)]
483    fn eof_offset(&self) -> usize {
484        let offset = self.0.eof_offset() * 8;
485        if offset == 0 {
486            0
487        } else {
488            offset - self.1
489        }
490    }
491
492    #[inline(always)]
493    fn next_token(&mut self) -> Option<Self::Token> {
494        next_bit(self)
495    }
496
497    #[inline(always)]
498    fn peek_token(&self) -> Option<Self::Token> {
499        peek_bit(self)
500    }
501
502    #[inline(always)]
503    fn offset_for<P>(&self, predicate: P) -> Option<usize>
504    where
505        P: Fn(Self::Token) -> bool,
506    {
507        self.iter_offsets()
508            .find_map(|(o, b)| predicate(b).then_some(o))
509    }
510    #[inline(always)]
511    fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
512        if let Some(needed) = tokens
513            .checked_sub(self.eof_offset())
514            .and_then(NonZeroUsize::new)
515        {
516            Err(Needed::Size(needed))
517        } else {
518            Ok(tokens)
519        }
520    }
521    #[inline(always)]
522    fn next_slice(&mut self, offset: usize) -> Self::Slice {
523        let byte_offset = (offset + self.1) / 8;
524        let end_offset = (offset + self.1) % 8;
525        let s = self.0.next_slice(byte_offset);
526        let start_offset = self.1;
527        self.1 = end_offset;
528        (s, start_offset, end_offset)
529    }
530    #[inline(always)]
531    fn peek_slice(&self, offset: usize) -> Self::Slice {
532        let byte_offset = (offset + self.1) / 8;
533        let end_offset = (offset + self.1) % 8;
534        let s = self.0.peek_slice(byte_offset);
535        let start_offset = self.1;
536        (s, start_offset, end_offset)
537    }
538
539    #[inline(always)]
540    fn checkpoint(&self) -> Self::Checkpoint {
541        Checkpoint::<_, Self>::new((self.0.checkpoint(), self.1))
542    }
543    #[inline(always)]
544    fn reset(&mut self, checkpoint: &Self::Checkpoint) {
545        self.0.reset(&checkpoint.inner.0);
546        self.1 = checkpoint.inner.1;
547    }
548
549    #[inline(always)]
550    fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
551        &self.0
552    }
553}
554
555/// Iterator for [bit][crate::binary::bits] stream (`(I, usize)`)
556pub struct BitOffsets<I> {
557    i: (I, usize),
558    o: usize,
559}
560
561impl<I> Iterator for BitOffsets<I>
562where
563    I: Stream<Token = u8> + Clone,
564{
565    type Item = (usize, bool);
566    fn next(&mut self) -> Option<Self::Item> {
567        let b = next_bit(&mut self.i)?;
568        let o = self.o;
569
570        self.o += 1;
571
572        Some((o, b))
573    }
574}
575
576fn next_bit<I>(i: &mut (I, usize)) -> Option<bool>
577where
578    I: Stream<Token = u8> + Clone,
579{
580    if i.eof_offset() == 0 {
581        return None;
582    }
583    let offset = i.1;
584
585    let mut next_i = i.0.clone();
586    let byte = next_i.next_token()?;
587    let bit = (byte >> offset) & 0x1 == 0x1;
588
589    let next_offset = offset + 1;
590    if next_offset == 8 {
591        i.0 = next_i;
592        i.1 = 0;
593        Some(bit)
594    } else {
595        i.1 = next_offset;
596        Some(bit)
597    }
598}
599
600fn peek_bit<I>(i: &(I, usize)) -> Option<bool>
601where
602    I: Stream<Token = u8> + Clone,
603{
604    if i.eof_offset() == 0 {
605        return None;
606    }
607    let offset = i.1;
608
609    let mut next_i = i.0.clone();
610    let byte = next_i.next_token()?;
611    let bit = (byte >> offset) & 0x1 == 0x1;
612
613    let next_offset = offset + 1;
614    if next_offset == 8 {
615        Some(bit)
616    } else {
617        Some(bit)
618    }
619}
620
621/// Current parse locations offset
622///
623/// See [`LocatingSlice`] for adding location tracking to your [`Stream`]
624pub 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")]
636pub 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")]
654impl<'a, T, E> Recover<E> for &'a [T]
655where
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")]
677impl<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")]
697impl<I, E> Recover<E> for (I, usize)
698where
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.
722pub 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    fn is_partial(&self) -> bool {
739        Self::is_partial_supported()
740    }
741}
742
743impl<T> StreamIsPartial for &[T] {
744    type PartialState = ();
745
746    #[inline]
747    fn complete(&mut self) -> Self::PartialState {}
748
749    #[inline]
750    fn restore_partial(&mut self, _state: Self::PartialState) {}
751
752    #[inline(always)]
753    fn is_partial_supported() -> bool {
754        false
755    }
756}
757
758impl StreamIsPartial for &str {
759    type PartialState = ();
760
761    #[inline]
762    fn complete(&mut self) -> Self::PartialState {
763        // Already complete
764    }
765
766    #[inline]
767    fn restore_partial(&mut self, _state: Self::PartialState) {}
768
769    #[inline(always)]
770    fn is_partial_supported() -> bool {
771        false
772    }
773}
774
775impl<I> StreamIsPartial for (I, usize)
776where
777    I: StreamIsPartial,
778{
779    type PartialState = I::PartialState;
780
781    #[inline]
782    fn complete(&mut self) -> Self::PartialState {
783        self.0.complete()
784    }
785
786    #[inline]
787    fn restore_partial(&mut self, state: Self::PartialState) {
788        self.0.restore_partial(state);
789    }
790
791    #[inline(always)]
792    fn is_partial_supported() -> bool {
793        I::is_partial_supported()
794    }
795
796    #[inline(always)]
797    fn is_partial(&self) -> bool {
798        self.0.is_partial()
799    }
800}
801
802/// Useful functions to calculate the offset between slices and show a hexdump of a slice
803pub 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
815impl<T> Offset for &[T] {
816    #[inline]
817    fn offset_from(&self, start: &Self) -> usize {
818        let fst = (*start).as_ptr();
819        let snd = (*self).as_ptr();
820
821        debug_assert!(
822            fst <= snd,
823            "`Offset::offset_from({snd:?}, {fst:?})` only accepts slices of `self`"
824        );
825        (snd as usize - fst as usize) / crate::lib::std::mem::size_of::<T>()
826    }
827}
828
829impl<'a, T> Offset<<&'a [T] as Stream>::Checkpoint> for &'a [T]
830where
831    T: Clone + crate::lib::std::fmt::Debug,
832{
833    #[inline(always)]
834    fn offset_from(&self, other: &<&'a [T] as Stream>::Checkpoint) -> usize {
835        self.checkpoint().offset_from(other)
836    }
837}
838
839impl Offset for &str {
840    #[inline(always)]
841    fn offset_from(&self, start: &Self) -> usize {
842        self.as_bytes().offset_from(&start.as_bytes())
843    }
844}
845
846impl<'a> Offset<<&'a str as Stream>::Checkpoint> for &'a str {
847    #[inline(always)]
848    fn offset_from(&self, other: &<&'a str as Stream>::Checkpoint) -> usize {
849        self.checkpoint().offset_from(other)
850    }
851}
852
853impl<I> Offset for (I, usize)
854where
855    I: Offset,
856{
857    #[inline(always)]
858    fn offset_from(&self, start: &Self) -> usize {
859        self.0.offset_from(&start.0) * 8 + self.1 - start.1
860    }
861}
862
863impl<I> Offset<<(I, usize) as Stream>::Checkpoint> for (I, usize)
864where
865    I: Stream<Token = u8> + Clone,
866{
867    #[inline(always)]
868    fn offset_from(&self, other: &<(I, usize) as Stream>::Checkpoint) -> usize {
869        self.checkpoint().offset_from(other)
870    }
871}
872
873impl<I, S> Offset for Checkpoint<I, S>
874where
875    I: Offset,
876{
877    #[inline(always)]
878    fn offset_from(&self, start: &Self) -> usize {
879        self.inner.offset_from(&start.inner)
880    }
881}
882
883/// Helper trait for types that can be viewed as a byte slice
884pub trait AsBytes {
885    /// Casts the input type to a byte slice
886    fn as_bytes(&self) -> &[u8];
887}
888
889impl AsBytes for &[u8] {
890    #[inline(always)]
891    fn as_bytes(&self) -> &[u8] {
892        self
893    }
894}
895
896/// Helper trait for types that can be viewed as a byte slice
897pub trait AsBStr {
898    /// Casts the input type to a byte slice
899    fn as_bstr(&self) -> &[u8];
900}
901
902impl AsBStr for &[u8] {
903    #[inline(always)]
904    fn as_bstr(&self) -> &[u8] {
905        self
906    }
907}
908
909impl AsBStr for &str {
910    #[inline(always)]
911    fn as_bstr(&self) -> &[u8] {
912        (*self).as_bytes()
913    }
914}
915
916/// Result of [`Compare::compare`]
917#[derive(Debug, Eq, PartialEq)]
918pub 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
932pub trait Compare<T> {
933    /// Compares self to another value for equality
934    fn compare(&self, t: T) -> CompareResult;
935}
936
937impl<'b> Compare<&'b [u8]> for &[u8] {
938    #[inline]
939    fn compare(&self, t: &'b [u8]) -> CompareResult {
940        if t.iter().zip(*self).any(|(a, b)| a != b) {
941            CompareResult::Error
942        } else if self.len() < t.slice_len() {
943            CompareResult::Incomplete
944        } else {
945            CompareResult::Ok(t.slice_len())
946        }
947    }
948}
949
950impl<'b> Compare<AsciiCaseless<&'b [u8]>> for &[u8] {
951    #[inline]
952    fn compare(&self, t: AsciiCaseless<&'b [u8]>) -> CompareResult {
953        if t.0
954            .iter()
955            .zip(*self)
956            .any(|(a, b)| !a.eq_ignore_ascii_case(b))
957        {
958            CompareResult::Error
959        } else if self.len() < t.slice_len() {
960            CompareResult::Incomplete
961        } else {
962            CompareResult::Ok(t.slice_len())
963        }
964    }
965}
966
967impl<const LEN: usize> Compare<[u8; LEN]> for &[u8] {
968    #[inline(always)]
969    fn compare(&self, t: [u8; LEN]) -> CompareResult {
970        self.compare(&t[..])
971    }
972}
973
974impl<const LEN: usize> Compare<AsciiCaseless<[u8; LEN]>> for &[u8] {
975    #[inline(always)]
976    fn compare(&self, t: AsciiCaseless<[u8; LEN]>) -> CompareResult {
977        self.compare(AsciiCaseless(&t.0[..]))
978    }
979}
980
981impl<'b, const LEN: usize> Compare<&'b [u8; LEN]> for &[u8] {
982    #[inline(always)]
983    fn compare(&self, t: &'b [u8; LEN]) -> CompareResult {
984        self.compare(&t[..])
985    }
986}
987
988impl<'b, const LEN: usize> Compare<AsciiCaseless<&'b [u8; LEN]>> for &[u8] {
989    #[inline(always)]
990    fn compare(&self, t: AsciiCaseless<&'b [u8; LEN]>) -> CompareResult {
991        self.compare(AsciiCaseless(&t.0[..]))
992    }
993}
994
995impl<'b> Compare<&'b str> for &[u8] {
996    #[inline(always)]
997    fn compare(&self, t: &'b str) -> CompareResult {
998        self.compare(t.as_bytes())
999    }
1000}
1001
1002impl<'b> Compare<AsciiCaseless<&'b str>> for &[u8] {
1003    #[inline(always)]
1004    fn compare(&self, t: AsciiCaseless<&'b str>) -> CompareResult {
1005        self.compare(AsciiCaseless(t.0.as_bytes()))
1006    }
1007}
1008
1009impl Compare<u8> for &[u8] {
1010    #[inline]
1011    fn compare(&self, t: u8) -> CompareResult {
1012        match self.first().copied() {
1013            Some(c) if t == c => CompareResult::Ok(t.slice_len()),
1014            Some(_) => CompareResult::Error,
1015            None => CompareResult::Incomplete,
1016        }
1017    }
1018}
1019
1020impl Compare<AsciiCaseless<u8>> for &[u8] {
1021    #[inline]
1022    fn compare(&self, t: AsciiCaseless<u8>) -> CompareResult {
1023        match self.first() {
1024            Some(c) if t.0.eq_ignore_ascii_case(c) => CompareResult::Ok(t.slice_len()),
1025            Some(_) => CompareResult::Error,
1026            None => CompareResult::Incomplete,
1027        }
1028    }
1029}
1030
1031impl Compare<char> for &[u8] {
1032    #[inline(always)]
1033    fn compare(&self, t: char) -> CompareResult {
1034        self.compare(t.encode_utf8(&mut [0; 4]).as_bytes())
1035    }
1036}
1037
1038impl Compare<AsciiCaseless<char>> for &[u8] {
1039    #[inline(always)]
1040    fn compare(&self, t: AsciiCaseless<char>) -> CompareResult {
1041        self.compare(AsciiCaseless(t.0.encode_utf8(&mut [0; 4]).as_bytes()))
1042    }
1043}
1044
1045impl<'b> Compare<&'b str> for &str {
1046    #[inline(always)]
1047    fn compare(&self, t: &'b str) -> CompareResult {
1048        self.as_bytes().compare(t.as_bytes())
1049    }
1050}
1051
1052impl<'b> Compare<AsciiCaseless<&'b str>> for &str {
1053    #[inline(always)]
1054    fn compare(&self, t: AsciiCaseless<&'b str>) -> CompareResult {
1055        self.as_bytes().compare(t.as_bytes())
1056    }
1057}
1058
1059impl Compare<char> for &str {
1060    #[inline(always)]
1061    fn compare(&self, t: char) -> CompareResult {
1062        self.as_bytes().compare(t)
1063    }
1064}
1065
1066impl Compare<AsciiCaseless<char>> for &str {
1067    #[inline(always)]
1068    fn compare(&self, t: AsciiCaseless<char>) -> CompareResult {
1069        self.as_bytes().compare(t)
1070    }
1071}
1072
1073/// Look for a slice in self
1074pub 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
1079impl<'s> FindSlice<&'s [u8]> for &[u8] {
1080    #[inline(always)]
1081    fn find_slice(&self, substr: &'s [u8]) -> Option<crate::lib::std::ops::Range<usize>> {
1082        memmem(self, substr)
1083    }
1084}
1085
1086impl<'s> FindSlice<(&'s [u8],)> for &[u8] {
1087    #[inline(always)]
1088    fn find_slice(&self, substr: (&'s [u8],)) -> Option<crate::lib::std::ops::Range<usize>> {
1089        memmem(self, substr.0)
1090    }
1091}
1092
1093impl<'s> FindSlice<(&'s [u8], &'s [u8])> for &[u8] {
1094    #[inline(always)]
1095    fn find_slice(
1096        &self,
1097        substr: (&'s [u8], &'s [u8]),
1098    ) -> Option<crate::lib::std::ops::Range<usize>> {
1099        memmem2(self, substr)
1100    }
1101}
1102
1103impl<'s> FindSlice<(&'s [u8], &'s [u8], &'s [u8])> for &[u8] {
1104    #[inline(always)]
1105    fn find_slice(
1106        &self,
1107        substr: (&'s [u8], &'s [u8], &'s [u8]),
1108    ) -> Option<crate::lib::std::ops::Range<usize>> {
1109        memmem3(self, substr)
1110    }
1111}
1112
1113impl FindSlice<char> for &[u8] {
1114    #[inline(always)]
1115    fn find_slice(&self, substr: char) -> Option<crate::lib::std::ops::Range<usize>> {
1116        let mut b = [0; 4];
1117        let substr = substr.encode_utf8(&mut b);
1118        self.find_slice(&*substr)
1119    }
1120}
1121
1122impl FindSlice<(char,)> for &[u8] {
1123    #[inline(always)]
1124    fn find_slice(&self, substr: (char,)) -> Option<crate::lib::std::ops::Range<usize>> {
1125        let mut b = [0; 4];
1126        let substr0 = substr.0.encode_utf8(&mut b);
1127        self.find_slice((&*substr0,))
1128    }
1129}
1130
1131impl FindSlice<(char, char)> for &[u8] {
1132    #[inline(always)]
1133    fn find_slice(&self, substr: (char, char)) -> Option<crate::lib::std::ops::Range<usize>> {
1134        let mut b = [0; 4];
1135        let substr0 = substr.0.encode_utf8(&mut b);
1136        let mut b = [0; 4];
1137        let substr1 = substr.1.encode_utf8(&mut b);
1138        self.find_slice((&*substr0, &*substr1))
1139    }
1140}
1141
1142impl FindSlice<(char, char, char)> for &[u8] {
1143    #[inline(always)]
1144    fn find_slice(&self, substr: (char, char, char)) -> Option<crate::lib::std::ops::Range<usize>> {
1145        let mut b = [0; 4];
1146        let substr0 = substr.0.encode_utf8(&mut b);
1147        let mut b = [0; 4];
1148        let substr1 = substr.1.encode_utf8(&mut b);
1149        let mut b = [0; 4];
1150        let substr2 = substr.2.encode_utf8(&mut b);
1151        self.find_slice((&*substr0, &*substr1, &*substr2))
1152    }
1153}
1154
1155impl FindSlice<u8> for &[u8] {
1156    #[inline(always)]
1157    fn find_slice(&self, substr: u8) -> Option<crate::lib::std::ops::Range<usize>> {
1158        memchr(substr, self).map(|i| i..i + 1)
1159    }
1160}
1161
1162impl FindSlice<(u8,)> for &[u8] {
1163    #[inline(always)]
1164    fn find_slice(&self, substr: (u8,)) -> Option<crate::lib::std::ops::Range<usize>> {
1165        memchr(substr.0, self).map(|i| i..i + 1)
1166    }
1167}
1168
1169impl FindSlice<(u8, u8)> for &[u8] {
1170    #[inline(always)]
1171    fn find_slice(&self, substr: (u8, u8)) -> Option<crate::lib::std::ops::Range<usize>> {
1172        memchr2(substr, self).map(|i| i..i + 1)
1173    }
1174}
1175
1176impl FindSlice<(u8, u8, u8)> for &[u8] {
1177    #[inline(always)]
1178    fn find_slice(&self, substr: (u8, u8, u8)) -> Option<crate::lib::std::ops::Range<usize>> {
1179        memchr3(substr, self).map(|i| i..i + 1)
1180    }
1181}
1182
1183impl<'s> FindSlice<&'s str> for &[u8] {
1184    #[inline(always)]
1185    fn find_slice(&self, substr: &'s str) -> Option<crate::lib::std::ops::Range<usize>> {
1186        self.find_slice(substr.as_bytes())
1187    }
1188}
1189
1190impl<'s> FindSlice<(&'s str,)> for &[u8] {
1191    #[inline(always)]
1192    fn find_slice(&self, substr: (&'s str,)) -> Option<crate::lib::std::ops::Range<usize>> {
1193        memmem(self, substr.0.as_bytes())
1194    }
1195}
1196
1197impl<'s> FindSlice<(&'s str, &'s str)> for &[u8] {
1198    #[inline(always)]
1199    fn find_slice(&self, substr: (&'s str, &'s str)) -> Option<crate::lib::std::ops::Range<usize>> {
1200        memmem2(self, (substr.0.as_bytes(), substr.1.as_bytes()))
1201    }
1202}
1203
1204impl<'s> FindSlice<(&'s str, &'s str, &'s str)> for &[u8] {
1205    #[inline(always)]
1206    fn find_slice(
1207        &self,
1208        substr: (&'s str, &'s str, &'s str),
1209    ) -> Option<crate::lib::std::ops::Range<usize>> {
1210        memmem3(
1211            self,
1212            (
1213                substr.0.as_bytes(),
1214                substr.1.as_bytes(),
1215                substr.2.as_bytes(),
1216            ),
1217        )
1218    }
1219}
1220
1221impl<'s> FindSlice<&'s str> for &str {
1222    #[inline(always)]
1223    fn find_slice(&self, substr: &'s str) -> Option<crate::lib::std::ops::Range<usize>> {
1224        self.as_bytes().find_slice(substr)
1225    }
1226}
1227
1228impl<'s> FindSlice<(&'s str,)> for &str {
1229    #[inline(always)]
1230    fn find_slice(&self, substr: (&'s str,)) -> Option<crate::lib::std::ops::Range<usize>> {
1231        self.as_bytes().find_slice(substr)
1232    }
1233}
1234
1235impl<'s> FindSlice<(&'s str, &'s str)> for &str {
1236    #[inline(always)]
1237    fn find_slice(&self, substr: (&'s str, &'s str)) -> Option<crate::lib::std::ops::Range<usize>> {
1238        self.as_bytes().find_slice(substr)
1239    }
1240}
1241
1242impl<'s> FindSlice<(&'s str, &'s str, &'s str)> for &str {
1243    #[inline(always)]
1244    fn find_slice(
1245        &self,
1246        substr: (&'s str, &'s str, &'s str),
1247    ) -> Option<crate::lib::std::ops::Range<usize>> {
1248        self.as_bytes().find_slice(substr)
1249    }
1250}
1251
1252impl FindSlice<char> for &str {
1253    #[inline(always)]
1254    fn find_slice(&self, substr: char) -> Option<crate::lib::std::ops::Range<usize>> {
1255        self.as_bytes().find_slice(substr)
1256    }
1257}
1258
1259impl FindSlice<(char,)> for &str {
1260    #[inline(always)]
1261    fn find_slice(&self, substr: (char,)) -> Option<crate::lib::std::ops::Range<usize>> {
1262        self.as_bytes().find_slice(substr)
1263    }
1264}
1265
1266impl FindSlice<(char, char)> for &str {
1267    #[inline(always)]
1268    fn find_slice(&self, substr: (char, char)) -> Option<crate::lib::std::ops::Range<usize>> {
1269        self.as_bytes().find_slice(substr)
1270    }
1271}
1272
1273impl FindSlice<(char, char, char)> for &str {
1274    #[inline(always)]
1275    fn find_slice(&self, substr: (char, char, char)) -> Option<crate::lib::std::ops::Range<usize>> {
1276        self.as_bytes().find_slice(substr)
1277    }
1278}
1279
1280/// Used to integrate `str`'s `parse()` method
1281pub 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
1289impl<R: FromStr> ParseSlice<R> for &[u8] {
1290    #[inline(always)]
1291    fn parse_slice(&self) -> Option<R> {
1292        from_utf8(self).ok().and_then(|s| s.parse().ok())
1293    }
1294}
1295
1296impl<R: FromStr> ParseSlice<R> for &str {
1297    #[inline(always)]
1298    fn parse_slice(&self) -> Option<R> {
1299        self.parse().ok()
1300    }
1301}
1302
1303/// Convert a `Stream` into an appropriate `Output` type
1304pub trait UpdateSlice: Stream {
1305    /// Convert an `Output` type to be used as `Stream`
1306    fn update_slice(self, inner: Self::Slice) -> Self;
1307}
1308
1309impl<T> UpdateSlice for &[T]
1310where
1311    T: Clone + crate::lib::std::fmt::Debug,
1312{
1313    #[inline(always)]
1314    fn update_slice(self, inner: Self::Slice) -> Self {
1315        inner
1316    }
1317}
1318
1319impl UpdateSlice for &str {
1320    #[inline(always)]
1321    fn update_slice(self, inner: Self::Slice) -> Self {
1322        inner
1323    }
1324}
1325
1326/// Ensure checkpoint details are kept private
1327pub struct Checkpoint<T, S> {
1328    inner: T,
1329    stream: core::marker::PhantomData<S>,
1330}
1331
1332impl<T, S> Checkpoint<T, S> {
1333    fn new(inner: T) -> Self {
1334        Self {
1335            inner,
1336            stream: Default::default(),
1337        }
1338    }
1339}
1340
1341impl<T: Copy, S> Copy for Checkpoint<T, S> {}
1342
1343impl<T: Clone, S> Clone for Checkpoint<T, S> {
1344    #[inline(always)]
1345    fn clone(&self) -> Self {
1346        Self {
1347            inner: self.inner.clone(),
1348            stream: Default::default(),
1349        }
1350    }
1351}
1352
1353impl<T: PartialOrd, S> PartialOrd for Checkpoint<T, S> {
1354    #[inline(always)]
1355    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1356        self.inner.partial_cmp(&other.inner)
1357    }
1358}
1359
1360impl<T: Ord, S> Ord for Checkpoint<T, S> {
1361    #[inline(always)]
1362    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1363        self.inner.cmp(&other.inner)
1364    }
1365}
1366
1367impl<T: PartialEq, S> PartialEq for Checkpoint<T, S> {
1368    #[inline(always)]
1369    fn eq(&self, other: &Self) -> bool {
1370        self.inner.eq(&other.inner)
1371    }
1372}
1373
1374impl<T: Eq, S> Eq for Checkpoint<T, S> {}
1375
1376impl<T: crate::lib::std::fmt::Debug, S> crate::lib::std::fmt::Debug for Checkpoint<T, S> {
1377    fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result {
1378        self.inner.fmt(f)
1379    }
1380}
1381
1382/// Abstracts something which can extend an `Extend`.
1383/// Used to build modified input slices in `escaped_transform`
1384pub 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
1391impl<T> Accumulate<T> for () {
1392    #[inline(always)]
1393    fn initial(_capacity: Option<usize>) -> Self {}
1394    #[inline(always)]
1395    fn accumulate(&mut self, _acc: T) {}
1396}
1397
1398impl<T> Accumulate<T> for usize {
1399    #[inline(always)]
1400    fn initial(_capacity: Option<usize>) -> Self {
1401        0
1402    }
1403    #[inline(always)]
1404    fn accumulate(&mut self, _acc: T) {
1405        *self += 1;
1406    }
1407}
1408
1409#[cfg(feature = "alloc")]
1410impl<T> Accumulate<T> for Vec<T> {
1411    #[inline(always)]
1412    fn initial(capacity: Option<usize>) -> Self {
1413        match capacity {
1414            Some(capacity) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
1415            None => Vec::new(),
1416        }
1417    }
1418    #[inline(always)]
1419    fn accumulate(&mut self, acc: T) {
1420        self.push(acc);
1421    }
1422}
1423
1424#[cfg(feature = "alloc")]
1425impl<'i, T: Clone> Accumulate<&'i [T]> for Vec<T> {
1426    #[inline(always)]
1427    fn initial(capacity: Option<usize>) -> Self {
1428        match capacity {
1429            Some(capacity) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
1430            None => Vec::new(),
1431        }
1432    }
1433    #[inline(always)]
1434    fn accumulate(&mut self, acc: &'i [T]) {
1435        self.extend(acc.iter().cloned());
1436    }
1437}
1438
1439#[cfg(feature = "alloc")]
1440impl Accumulate<char> for String {
1441    #[inline(always)]
1442    fn initial(capacity: Option<usize>) -> Self {
1443        match capacity {
1444            Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1445            None => String::new(),
1446        }
1447    }
1448    #[inline(always)]
1449    fn accumulate(&mut self, acc: char) {
1450        self.push(acc);
1451    }
1452}
1453
1454#[cfg(feature = "alloc")]
1455impl<'i> Accumulate<&'i str> for String {
1456    #[inline(always)]
1457    fn initial(capacity: Option<usize>) -> Self {
1458        match capacity {
1459            Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1460            None => String::new(),
1461        }
1462    }
1463    #[inline(always)]
1464    fn accumulate(&mut self, acc: &'i str) {
1465        self.push_str(acc);
1466    }
1467}
1468
1469#[cfg(feature = "alloc")]
1470impl<K, V> Accumulate<(K, V)> for BTreeMap<K, V>
1471where
1472    K: crate::lib::std::cmp::Ord,
1473{
1474    #[inline(always)]
1475    fn initial(_capacity: Option<usize>) -> Self {
1476        BTreeMap::new()
1477    }
1478    #[inline(always)]
1479    fn accumulate(&mut self, (key, value): (K, V)) {
1480        self.insert(key, value);
1481    }
1482}
1483
1484#[cfg(feature = "std")]
1485impl<K, V, S> Accumulate<(K, V)> for HashMap<K, V, S>
1486where
1487    K: crate::lib::std::cmp::Eq + crate::lib::std::hash::Hash,
1488    S: BuildHasher + Default,
1489{
1490    #[inline(always)]
1491    fn initial(capacity: Option<usize>) -> Self {
1492        let h = S::default();
1493        match capacity {
1494            Some(capacity) => {
1495                HashMap::with_capacity_and_hasher(clamp_capacity::<(K, V)>(capacity), h)
1496            }
1497            None => HashMap::with_hasher(h),
1498        }
1499    }
1500    #[inline(always)]
1501    fn accumulate(&mut self, (key, value): (K, V)) {
1502        self.insert(key, value);
1503    }
1504}
1505
1506#[cfg(feature = "alloc")]
1507impl<K> Accumulate<K> for BTreeSet<K>
1508where
1509    K: crate::lib::std::cmp::Ord,
1510{
1511    #[inline(always)]
1512    fn initial(_capacity: Option<usize>) -> Self {
1513        BTreeSet::new()
1514    }
1515    #[inline(always)]
1516    fn accumulate(&mut self, key: K) {
1517        self.insert(key);
1518    }
1519}
1520
1521#[cfg(feature = "std")]
1522impl<K, S> Accumulate<K> for HashSet<K, S>
1523where
1524    K: crate::lib::std::cmp::Eq + crate::lib::std::hash::Hash,
1525    S: BuildHasher + Default,
1526{
1527    #[inline(always)]
1528    fn initial(capacity: Option<usize>) -> Self {
1529        let h = S::default();
1530        match capacity {
1531            Some(capacity) => HashSet::with_capacity_and_hasher(clamp_capacity::<K>(capacity), h),
1532            None => HashSet::with_hasher(h),
1533        }
1534    }
1535    #[inline(always)]
1536    fn accumulate(&mut self, key: K) {
1537        self.insert(key);
1538    }
1539}
1540
1541#[cfg(feature = "alloc")]
1542#[inline]
1543pub(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    let max_initial_capacity =
1556        MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::<T>().max(1);
1557    capacity.min(max_initial_capacity)
1558}
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
1566pub trait ToUsize {
1567    /// converts self to usize
1568    fn to_usize(&self) -> usize;
1569}
1570
1571impl ToUsize for u8 {
1572    #[inline(always)]
1573    fn to_usize(&self) -> usize {
1574        *self as usize
1575    }
1576}
1577
1578impl ToUsize for u16 {
1579    #[inline(always)]
1580    fn to_usize(&self) -> usize {
1581        *self as usize
1582    }
1583}
1584
1585impl ToUsize for usize {
1586    #[inline(always)]
1587    fn to_usize(&self) -> usize {
1588        *self
1589    }
1590}
1591
1592#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
1593impl ToUsize for u32 {
1594    #[inline(always)]
1595    fn to_usize(&self) -> usize {
1596        *self as usize
1597    }
1598}
1599
1600#[cfg(target_pointer_width = "64")]
1601impl ToUsize for u64 {
1602    #[inline(always)]
1603    fn to_usize(&self) -> usize {
1604        *self as usize
1605    }
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)]
1611pub 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
1651impl AsChar for u8 {
1652    #[inline(always)]
1653    fn as_char(self) -> char {
1654        self as char
1655    }
1656    #[inline]
1657    fn is_alpha(self) -> bool {
1658        matches!(self, 0x41..=0x5A | 0x61..=0x7A)
1659    }
1660    #[inline]
1661    fn is_alphanum(self) -> bool {
1662        self.is_alpha() || self.is_dec_digit()
1663    }
1664    #[inline]
1665    fn is_dec_digit(self) -> bool {
1666        matches!(self, 0x30..=0x39)
1667    }
1668    #[inline]
1669    fn is_hex_digit(self) -> bool {
1670        matches!(self, 0x30..=0x39 | 0x41..=0x46 | 0x61..=0x66)
1671    }
1672    #[inline]
1673    fn is_oct_digit(self) -> bool {
1674        matches!(self, 0x30..=0x37)
1675    }
1676    #[inline]
1677    fn len(self) -> usize {
1678        1
1679    }
1680    #[inline]
1681    fn is_space(self) -> bool {
1682        self == b' ' || self == b'\t'
1683    }
1684    #[inline]
1685    fn is_newline(self) -> bool {
1686        self == b'\n'
1687    }
1688}
1689
1690impl AsChar for &u8 {
1691    #[inline(always)]
1692    fn as_char(self) -> char {
1693        (*self).as_char()
1694    }
1695    #[inline(always)]
1696    fn is_alpha(self) -> bool {
1697        (*self).is_alpha()
1698    }
1699    #[inline(always)]
1700    fn is_alphanum(self) -> bool {
1701        (*self).is_alphanum()
1702    }
1703    #[inline(always)]
1704    fn is_dec_digit(self) -> bool {
1705        (*self).is_dec_digit()
1706    }
1707    #[inline(always)]
1708    fn is_hex_digit(self) -> bool {
1709        (*self).is_hex_digit()
1710    }
1711    #[inline(always)]
1712    fn is_oct_digit(self) -> bool {
1713        (*self).is_oct_digit()
1714    }
1715    #[inline(always)]
1716    fn len(self) -> usize {
1717        (*self).len()
1718    }
1719    #[inline(always)]
1720    fn is_space(self) -> bool {
1721        (*self).is_space()
1722    }
1723    #[inline(always)]
1724    fn is_newline(self) -> bool {
1725        (*self).is_newline()
1726    }
1727}
1728
1729impl AsChar for char {
1730    #[inline(always)]
1731    fn as_char(self) -> char {
1732        self
1733    }
1734    #[inline]
1735    fn is_alpha(self) -> bool {
1736        self.is_ascii_alphabetic()
1737    }
1738    #[inline]
1739    fn is_alphanum(self) -> bool {
1740        self.is_alpha() || self.is_dec_digit()
1741    }
1742    #[inline]
1743    fn is_dec_digit(self) -> bool {
1744        self.is_ascii_digit()
1745    }
1746    #[inline]
1747    fn is_hex_digit(self) -> bool {
1748        self.is_ascii_hexdigit()
1749    }
1750    #[inline]
1751    fn is_oct_digit(self) -> bool {
1752        self.is_digit(8)
1753    }
1754    #[inline]
1755    fn len(self) -> usize {
1756        self.len_utf8()
1757    }
1758    #[inline]
1759    fn is_space(self) -> bool {
1760        self == ' ' || self == '\t'
1761    }
1762    #[inline]
1763    fn is_newline(self) -> bool {
1764        self == '\n'
1765    }
1766}
1767
1768impl AsChar for &char {
1769    #[inline(always)]
1770    fn as_char(self) -> char {
1771        (*self).as_char()
1772    }
1773    #[inline(always)]
1774    fn is_alpha(self) -> bool {
1775        (*self).is_alpha()
1776    }
1777    #[inline(always)]
1778    fn is_alphanum(self) -> bool {
1779        (*self).is_alphanum()
1780    }
1781    #[inline(always)]
1782    fn is_dec_digit(self) -> bool {
1783        (*self).is_dec_digit()
1784    }
1785    #[inline(always)]
1786    fn is_hex_digit(self) -> bool {
1787        (*self).is_hex_digit()
1788    }
1789    #[inline(always)]
1790    fn is_oct_digit(self) -> bool {
1791        (*self).is_oct_digit()
1792    }
1793    #[inline(always)]
1794    fn len(self) -> usize {
1795        (*self).len()
1796    }
1797    #[inline(always)]
1798    fn is_space(self) -> bool {
1799        (*self).is_space()
1800    }
1801    #[inline(always)]
1802    fn is_newline(self) -> bool {
1803        (*self).is_newline()
1804    }
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/// ```
1831pub trait ContainsToken<T> {
1832    /// Returns true if self contains the token
1833    fn contains_token(&self, token: T) -> bool;
1834}
1835
1836impl ContainsToken<u8> for u8 {
1837    #[inline(always)]
1838    fn contains_token(&self, token: u8) -> bool {
1839        *self == token
1840    }
1841}
1842
1843impl ContainsToken<&u8> for u8 {
1844    #[inline(always)]
1845    fn contains_token(&self, token: &u8) -> bool {
1846        self.contains_token(*token)
1847    }
1848}
1849
1850impl ContainsToken<char> for u8 {
1851    #[inline(always)]
1852    fn contains_token(&self, token: char) -> bool {
1853        self.as_char() == token
1854    }
1855}
1856
1857impl ContainsToken<&char> for u8 {
1858    #[inline(always)]
1859    fn contains_token(&self, token: &char) -> bool {
1860        self.contains_token(*token)
1861    }
1862}
1863
1864impl<C: AsChar> ContainsToken<C> for char {
1865    #[inline(always)]
1866    fn contains_token(&self, token: C) -> bool {
1867        *self == token.as_char()
1868    }
1869}
1870
1871impl<C, F: Fn(C) -> bool> ContainsToken<C> for F {
1872    #[inline(always)]
1873    fn contains_token(&self, token: C) -> bool {
1874        self(token)
1875    }
1876}
1877
1878impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::Range<C2> {
1879    #[inline(always)]
1880    fn contains_token(&self, token: C1) -> bool {
1881        let start = self.start.clone().as_char();
1882        let end = self.end.clone().as_char();
1883        (start..end).contains(&token.as_char())
1884    }
1885}
1886
1887impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1>
1888    for crate::lib::std::ops::RangeInclusive<C2>
1889{
1890    #[inline(always)]
1891    fn contains_token(&self, token: C1) -> bool {
1892        let start = self.start().clone().as_char();
1893        let end = self.end().clone().as_char();
1894        (start..=end).contains(&token.as_char())
1895    }
1896}
1897
1898impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::RangeFrom<C2> {
1899    #[inline(always)]
1900    fn contains_token(&self, token: C1) -> bool {
1901        let start = self.start.clone().as_char();
1902        (start..).contains(&token.as_char())
1903    }
1904}
1905
1906impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::RangeTo<C2> {
1907    #[inline(always)]
1908    fn contains_token(&self, token: C1) -> bool {
1909        let end = self.end.clone().as_char();
1910        (..end).contains(&token.as_char())
1911    }
1912}
1913
1914impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1>
1915    for crate::lib::std::ops::RangeToInclusive<C2>
1916{
1917    #[inline(always)]
1918    fn contains_token(&self, token: C1) -> bool {
1919        let end = self.end.clone().as_char();
1920        (..=end).contains(&token.as_char())
1921    }
1922}
1923
1924impl<C1: AsChar> ContainsToken<C1> for crate::lib::std::ops::RangeFull {
1925    #[inline(always)]
1926    fn contains_token(&self, _token: C1) -> bool {
1927        true
1928    }
1929}
1930
1931impl<C: AsChar> ContainsToken<C> for &'_ [u8] {
1932    #[inline]
1933    fn contains_token(&self, token: C) -> bool {
1934        let token = token.as_char();
1935        self.iter().any(|t| t.as_char() == token)
1936    }
1937}
1938
1939impl<C: AsChar> ContainsToken<C> for &'_ [char] {
1940    #[inline]
1941    fn contains_token(&self, token: C) -> bool {
1942        let token = token.as_char();
1943        self.iter().any(|t| *t == token)
1944    }
1945}
1946
1947impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [u8; LEN] {
1948    #[inline]
1949    fn contains_token(&self, token: C) -> bool {
1950        let token = token.as_char();
1951        self.iter().any(|t| t.as_char() == token)
1952    }
1953}
1954
1955impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [char; LEN] {
1956    #[inline]
1957    fn contains_token(&self, token: C) -> bool {
1958        let token = token.as_char();
1959        self.iter().any(|t| *t == token)
1960    }
1961}
1962
1963impl<const LEN: usize, C: AsChar> ContainsToken<C> for [u8; LEN] {
1964    #[inline]
1965    fn contains_token(&self, token: C) -> bool {
1966        let token = token.as_char();
1967        self.iter().any(|t| t.as_char() == token)
1968    }
1969}
1970
1971impl<const LEN: usize, C: AsChar> ContainsToken<C> for [char; LEN] {
1972    #[inline]
1973    fn contains_token(&self, token: C) -> bool {
1974        let token = token.as_char();
1975        self.iter().any(|t| *t == token)
1976    }
1977}
1978
1979impl<T> ContainsToken<T> for () {
1980    #[inline(always)]
1981    fn contains_token(&self, _token: T) -> bool {
1982        false
1983    }
1984}
1985
1986macro_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      fn contains_token(&self, token: T) -> bool {
1996        let ($(ref $haystack),+,) = *self;
1997        $($haystack.contains_token(token.clone()) || )+ false
1998      }
1999    }
2000  )
2001}
2002
2003macro_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
2016impl_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)]
2022fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
2023    memchr::memchr(token, slice)
2024}
2025
2026#[cfg(feature = "simd")]
2027#[inline(always)]
2028fn 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)]
2034fn 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)]
2040fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
2041    slice.iter().position(|t| *t == token)
2042}
2043
2044#[cfg(not(feature = "simd"))]
2045#[inline(always)]
2046fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
2047    slice.iter().position(|t| *t == token.0 || *t == token.1)
2048}
2049
2050#[cfg(not(feature = "simd"))]
2051#[inline(always)]
2052fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
2053    slice
2054        .iter()
2055        .position(|t| *t == token.0 || *t == token.1 || *t == token.2)
2056}
2057
2058#[inline(always)]
2059fn memmem(slice: &[u8], literal: &[u8]) -> Option<crate::lib::std::ops::Range<usize>> {
2060    match literal.len() {
2061        0 => Some(0..0),
2062        1 => memchr(literal[0], slice).map(|i| i..i + 1),
2063        _ => memmem_(slice, literal),
2064    }
2065}
2066
2067#[inline(always)]
2068fn memmem2(slice: &[u8], literal: (&[u8], &[u8])) -> Option<crate::lib::std::ops::Range<usize>> {
2069    match (literal.0.len(), literal.1.len()) {
2070        (0, _) | (_, 0) => Some(0..0),
2071        (1, 1) => memchr2((literal.0[0], literal.1[0]), slice).map(|i| i..i + 1),
2072        _ => memmem2_(slice, literal),
2073    }
2074}
2075
2076#[inline(always)]
2077fn memmem3(
2078    slice: &[u8],
2079    literal: (&[u8], &[u8], &[u8]),
2080) -> Option<crate::lib::std::ops::Range<usize>> {
2081    match (literal.0.len(), literal.1.len(), literal.2.len()) {
2082        (0, _, _) | (_, 0, _) | (_, _, 0) => Some(0..0),
2083        (1, 1, 1) => memchr3((literal.0[0], literal.1[0], literal.2[0]), slice).map(|i| i..i + 1),
2084        _ => memmem3_(slice, literal),
2085    }
2086}
2087
2088#[cfg(feature = "simd")]
2089#[inline(always)]
2090fn 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")]
2106fn 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")]
2127fn 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"))]
2155fn memmem_(slice: &[u8], literal: &[u8]) -> Option<crate::lib::std::ops::Range<usize>> {
2156    for i in 0..slice.len() {
2157        let subslice = &slice[i..];
2158        if subslice.starts_with(literal) {
2159            let i_end = i + literal.len();
2160            return Some(i..i_end);
2161        }
2162    }
2163    None
2164}
2165
2166#[cfg(not(feature = "simd"))]
2167fn memmem2_(slice: &[u8], literal: (&[u8], &[u8])) -> Option<crate::lib::std::ops::Range<usize>> {
2168    for i in 0..slice.len() {
2169        let subslice = &slice[i..];
2170        if subslice.starts_with(literal.0) {
2171            let i_end = i + literal.0.len();
2172            return Some(i..i_end);
2173        }
2174        if subslice.starts_with(literal.1) {
2175            let i_end = i + literal.1.len();
2176            return Some(i..i_end);
2177        }
2178    }
2179    None
2180}
2181
2182#[cfg(not(feature = "simd"))]
2183fn memmem3_(
2184    slice: &[u8],
2185    literal: (&[u8], &[u8], &[u8]),
2186) -> Option<crate::lib::std::ops::Range<usize>> {
2187    for i in 0..slice.len() {
2188        let subslice = &slice[i..];
2189        if subslice.starts_with(literal.0) {
2190            let i_end = i + literal.0.len();
2191            return Some(i..i_end);
2192        }
2193        if subslice.starts_with(literal.1) {
2194            let i_end = i + literal.1.len();
2195            return Some(i..i_end);
2196        }
2197        if subslice.starts_with(literal.2) {
2198            let i_end = i + literal.2.len();
2199            return Some(i..i_end);
2200        }
2201    }
2202    None
2203}