Skip to main content

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