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/// Used to build modified input slices in `escaped_transform`
1390pub trait Accumulate<T>: Sized {
1391    /// Create a new `Extend` of the correct type
1392    fn initial(capacity: Option<usize>) -> Self;
1393    /// Accumulate the input into an accumulator
1394    fn accumulate(&mut self, acc: T);
1395}
1396
1397impl<T> Accumulate<T> for () {
1398    #[inline(always)]
1399    fn initial(_capacity: Option<usize>) -> Self {}
1400    #[inline(always)]
1401    fn accumulate(&mut self, _acc: T) {}
1402}
1403
1404impl<T> Accumulate<T> for usize {
1405    #[inline(always)]
1406    fn initial(_capacity: Option<usize>) -> Self {
1407        0
1408    }
1409    #[inline(always)]
1410    fn accumulate(&mut self, _acc: T) {
1411        *self += 1;
1412    }
1413}
1414
1415#[cfg(feature = "alloc")]
1416impl<T> Accumulate<T> for Vec<T> {
1417    #[inline(always)]
1418    fn initial(capacity: Option<usize>) -> Self {
1419        match capacity {
1420            Some(capacity) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
1421            None => Vec::new(),
1422        }
1423    }
1424    #[inline(always)]
1425    fn accumulate(&mut self, acc: T) {
1426        self.push(acc);
1427    }
1428}
1429
1430#[cfg(feature = "alloc")]
1431impl<'i, T: Clone> Accumulate<&'i [T]> for Vec<T> {
1432    #[inline(always)]
1433    fn initial(capacity: Option<usize>) -> Self {
1434        match capacity {
1435            Some(capacity) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
1436            None => Vec::new(),
1437        }
1438    }
1439    #[inline(always)]
1440    fn accumulate(&mut self, acc: &'i [T]) {
1441        self.extend(acc.iter().cloned());
1442    }
1443}
1444
1445#[cfg(feature = "alloc")]
1446impl Accumulate<char> for String {
1447    #[inline(always)]
1448    fn initial(capacity: Option<usize>) -> Self {
1449        match capacity {
1450            Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1451            None => String::new(),
1452        }
1453    }
1454    #[inline(always)]
1455    fn accumulate(&mut self, acc: char) {
1456        self.push(acc);
1457    }
1458}
1459
1460#[cfg(feature = "alloc")]
1461impl<'i> Accumulate<&'i str> for String {
1462    #[inline(always)]
1463    fn initial(capacity: Option<usize>) -> Self {
1464        match capacity {
1465            Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1466            None => String::new(),
1467        }
1468    }
1469    #[inline(always)]
1470    fn accumulate(&mut self, acc: &'i str) {
1471        self.push_str(acc);
1472    }
1473}
1474
1475#[cfg(feature = "alloc")]
1476impl<'i> Accumulate<Cow<'i, str>> for String {
1477    #[inline(always)]
1478    fn initial(capacity: Option<usize>) -> Self {
1479        match capacity {
1480            Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1481            None => String::new(),
1482        }
1483    }
1484    #[inline(always)]
1485    fn accumulate(&mut self, acc: Cow<'i, str>) {
1486        self.push_str(&acc);
1487    }
1488}
1489
1490#[cfg(feature = "alloc")]
1491impl Accumulate<String> for String {
1492    #[inline(always)]
1493    fn initial(capacity: Option<usize>) -> Self {
1494        match capacity {
1495            Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1496            None => String::new(),
1497        }
1498    }
1499    #[inline(always)]
1500    fn accumulate(&mut self, acc: String) {
1501        self.push_str(&acc);
1502    }
1503}
1504
1505#[cfg(feature = "alloc")]
1506impl<K, V> Accumulate<(K, V)> for BTreeMap<K, V>
1507where
1508    K: core::cmp::Ord,
1509{
1510    #[inline(always)]
1511    fn initial(_capacity: Option<usize>) -> Self {
1512        BTreeMap::new()
1513    }
1514    #[inline(always)]
1515    fn accumulate(&mut self, (key, value): (K, V)) {
1516        self.insert(key, value);
1517    }
1518}
1519
1520#[cfg(feature = "std")]
1521impl<K, V, S> Accumulate<(K, V)> for HashMap<K, V, S>
1522where
1523    K: core::cmp::Eq + core::hash::Hash,
1524    S: BuildHasher + Default,
1525{
1526    #[inline(always)]
1527    fn initial(capacity: Option<usize>) -> Self {
1528        let h = S::default();
1529        match capacity {
1530            Some(capacity) => {
1531                HashMap::with_capacity_and_hasher(clamp_capacity::<(K, V)>(capacity), h)
1532            }
1533            None => HashMap::with_hasher(h),
1534        }
1535    }
1536    #[inline(always)]
1537    fn accumulate(&mut self, (key, value): (K, V)) {
1538        self.insert(key, value);
1539    }
1540}
1541
1542#[cfg(feature = "alloc")]
1543impl<K> Accumulate<K> for BTreeSet<K>
1544where
1545    K: core::cmp::Ord,
1546{
1547    #[inline(always)]
1548    fn initial(_capacity: Option<usize>) -> Self {
1549        BTreeSet::new()
1550    }
1551    #[inline(always)]
1552    fn accumulate(&mut self, key: K) {
1553        self.insert(key);
1554    }
1555}
1556
1557#[cfg(feature = "std")]
1558impl<K, S> Accumulate<K> for HashSet<K, S>
1559where
1560    K: core::cmp::Eq + core::hash::Hash,
1561    S: BuildHasher + Default,
1562{
1563    #[inline(always)]
1564    fn initial(capacity: Option<usize>) -> Self {
1565        let h = S::default();
1566        match capacity {
1567            Some(capacity) => HashSet::with_capacity_and_hasher(clamp_capacity::<K>(capacity), h),
1568            None => HashSet::with_hasher(h),
1569        }
1570    }
1571    #[inline(always)]
1572    fn accumulate(&mut self, key: K) {
1573        self.insert(key);
1574    }
1575}
1576
1577#[cfg(feature = "alloc")]
1578impl<'i, T: Clone> Accumulate<&'i [T]> for VecDeque<T> {
1579    #[inline(always)]
1580    fn initial(capacity: Option<usize>) -> Self {
1581        match capacity {
1582            Some(capacity) => VecDeque::with_capacity(clamp_capacity::<T>(capacity)),
1583            None => VecDeque::new(),
1584        }
1585    }
1586    #[inline(always)]
1587    fn accumulate(&mut self, acc: &'i [T]) {
1588        self.extend(acc.iter().cloned());
1589    }
1590}
1591
1592#[cfg(feature = "alloc")]
1593#[inline]
1594pub(crate) fn clamp_capacity<T>(capacity: usize) -> usize {
1595    /// Don't pre-allocate more than 64KiB when calling `Vec::with_capacity`.
1596    ///
1597    /// Pre-allocating memory is a nice optimization but count fields can't
1598    /// always be trusted. We should clamp initial capacities to some reasonable
1599    /// amount. This reduces the risk of a bogus count value triggering a panic
1600    /// due to an OOM error.
1601    ///
1602    /// This does not affect correctness. `winnow` will always read the full number
1603    /// of elements regardless of the capacity cap.
1604    const MAX_INITIAL_CAPACITY_BYTES: usize = 65536;
1605
1606    let max_initial_capacity = MAX_INITIAL_CAPACITY_BYTES / core::mem::size_of::<T>().max(1);
1607    capacity.min(max_initial_capacity)
1608}
1609
1610/// Helper trait to convert numbers to usize.
1611///
1612/// By default, usize implements `From<u8>` and `From<u16>` but not
1613/// `From<u32>` and `From<u64>` because that would be invalid on some
1614/// platforms. This trait implements the conversion for platforms
1615/// with 32 and 64 bits pointer platforms
1616pub trait ToUsize {
1617    /// converts self to usize
1618    fn to_usize(&self) -> usize;
1619}
1620
1621impl ToUsize for u8 {
1622    #[inline(always)]
1623    fn to_usize(&self) -> usize {
1624        *self as usize
1625    }
1626}
1627
1628impl ToUsize for u16 {
1629    #[inline(always)]
1630    fn to_usize(&self) -> usize {
1631        *self as usize
1632    }
1633}
1634
1635impl ToUsize for usize {
1636    #[inline(always)]
1637    fn to_usize(&self) -> usize {
1638        *self
1639    }
1640}
1641
1642#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
1643impl ToUsize for u32 {
1644    #[inline(always)]
1645    fn to_usize(&self) -> usize {
1646        *self as usize
1647    }
1648}
1649
1650#[cfg(target_pointer_width = "64")]
1651impl ToUsize for u64 {
1652    #[inline(always)]
1653    fn to_usize(&self) -> usize {
1654        *self as usize
1655    }
1656}
1657
1658/// Transforms a token into a char for basic string parsing
1659#[allow(clippy::len_without_is_empty)]
1660#[allow(clippy::wrong_self_convention)]
1661pub trait AsChar {
1662    /// Makes a char from self
1663    ///
1664    /// # Example
1665    ///
1666    /// ```
1667    /// use winnow::prelude::*;
1668    ///
1669    /// assert_eq!('a'.as_char(), 'a');
1670    /// assert_eq!(u8::MAX.as_char(), std::char::from_u32(u8::MAX as u32).unwrap());
1671    /// ```
1672    fn as_char(self) -> char;
1673
1674    /// Tests that self is an alphabetic character
1675    ///
1676    /// <div class="warning">
1677    ///
1678    /// **Warning:** for `&str` it matches alphabetic
1679    /// characters outside of the 52 ASCII letters
1680    ///
1681    /// </div>
1682    fn is_alpha(self) -> bool;
1683
1684    /// Tests that self is an alphabetic character
1685    /// or a decimal digit
1686    fn is_alphanum(self) -> bool;
1687    /// Tests that self is a decimal digit
1688    fn is_dec_digit(self) -> bool;
1689    /// Tests that self is an hex digit
1690    fn is_hex_digit(self) -> bool;
1691    /// Tests that self is an octal digit
1692    fn is_oct_digit(self) -> bool;
1693    /// Gets the len in bytes for self
1694    fn len(self) -> usize;
1695    /// Tests that self is ASCII space or tab
1696    fn is_space(self) -> bool;
1697    /// Tests if byte is ASCII newline: \n
1698    fn is_newline(self) -> bool;
1699}
1700
1701impl AsChar for u8 {
1702    #[inline(always)]
1703    fn as_char(self) -> char {
1704        self as char
1705    }
1706    #[inline]
1707    fn is_alpha(self) -> bool {
1708        matches!(self, 0x41..=0x5A | 0x61..=0x7A)
1709    }
1710    #[inline]
1711    fn is_alphanum(self) -> bool {
1712        self.is_alpha() || self.is_dec_digit()
1713    }
1714    #[inline]
1715    fn is_dec_digit(self) -> bool {
1716        matches!(self, 0x30..=0x39)
1717    }
1718    #[inline]
1719    fn is_hex_digit(self) -> bool {
1720        matches!(self, 0x30..=0x39 | 0x41..=0x46 | 0x61..=0x66)
1721    }
1722    #[inline]
1723    fn is_oct_digit(self) -> bool {
1724        matches!(self, 0x30..=0x37)
1725    }
1726    #[inline]
1727    fn len(self) -> usize {
1728        1
1729    }
1730    #[inline]
1731    fn is_space(self) -> bool {
1732        self == b' ' || self == b'\t'
1733    }
1734    #[inline]
1735    fn is_newline(self) -> bool {
1736        self == b'\n'
1737    }
1738}
1739
1740impl AsChar for &u8 {
1741    #[inline(always)]
1742    fn as_char(self) -> char {
1743        (*self).as_char()
1744    }
1745    #[inline(always)]
1746    fn is_alpha(self) -> bool {
1747        (*self).is_alpha()
1748    }
1749    #[inline(always)]
1750    fn is_alphanum(self) -> bool {
1751        (*self).is_alphanum()
1752    }
1753    #[inline(always)]
1754    fn is_dec_digit(self) -> bool {
1755        (*self).is_dec_digit()
1756    }
1757    #[inline(always)]
1758    fn is_hex_digit(self) -> bool {
1759        (*self).is_hex_digit()
1760    }
1761    #[inline(always)]
1762    fn is_oct_digit(self) -> bool {
1763        (*self).is_oct_digit()
1764    }
1765    #[inline(always)]
1766    fn len(self) -> usize {
1767        (*self).len()
1768    }
1769    #[inline(always)]
1770    fn is_space(self) -> bool {
1771        (*self).is_space()
1772    }
1773    #[inline(always)]
1774    fn is_newline(self) -> bool {
1775        (*self).is_newline()
1776    }
1777}
1778
1779impl AsChar for char {
1780    #[inline(always)]
1781    fn as_char(self) -> char {
1782        self
1783    }
1784    #[inline]
1785    fn is_alpha(self) -> bool {
1786        self.is_ascii_alphabetic()
1787    }
1788    #[inline]
1789    fn is_alphanum(self) -> bool {
1790        self.is_alpha() || self.is_dec_digit()
1791    }
1792    #[inline]
1793    fn is_dec_digit(self) -> bool {
1794        self.is_ascii_digit()
1795    }
1796    #[inline]
1797    fn is_hex_digit(self) -> bool {
1798        self.is_ascii_hexdigit()
1799    }
1800    #[inline]
1801    fn is_oct_digit(self) -> bool {
1802        self.is_digit(8)
1803    }
1804    #[inline]
1805    fn len(self) -> usize {
1806        self.len_utf8()
1807    }
1808    #[inline]
1809    fn is_space(self) -> bool {
1810        self == ' ' || self == '\t'
1811    }
1812    #[inline]
1813    fn is_newline(self) -> bool {
1814        self == '\n'
1815    }
1816}
1817
1818impl AsChar for &char {
1819    #[inline(always)]
1820    fn as_char(self) -> char {
1821        (*self).as_char()
1822    }
1823    #[inline(always)]
1824    fn is_alpha(self) -> bool {
1825        (*self).is_alpha()
1826    }
1827    #[inline(always)]
1828    fn is_alphanum(self) -> bool {
1829        (*self).is_alphanum()
1830    }
1831    #[inline(always)]
1832    fn is_dec_digit(self) -> bool {
1833        (*self).is_dec_digit()
1834    }
1835    #[inline(always)]
1836    fn is_hex_digit(self) -> bool {
1837        (*self).is_hex_digit()
1838    }
1839    #[inline(always)]
1840    fn is_oct_digit(self) -> bool {
1841        (*self).is_oct_digit()
1842    }
1843    #[inline(always)]
1844    fn len(self) -> usize {
1845        (*self).len()
1846    }
1847    #[inline(always)]
1848    fn is_space(self) -> bool {
1849        (*self).is_space()
1850    }
1851    #[inline(always)]
1852    fn is_newline(self) -> bool {
1853        (*self).is_newline()
1854    }
1855}
1856
1857/// Check if a token is in a set of possible tokens
1858///
1859/// While this can be implemented manually, you can also build up sets using:
1860/// - `b'c'` and `'c'`
1861/// - `b""`
1862/// - `|c| true`
1863/// - `b'a'..=b'z'`, `'a'..='z'` (etc for each [range type][std::ops])
1864/// - `(set1, set2, ...)`
1865///
1866/// # Example
1867///
1868/// For example, you could implement `hex_digit0` as:
1869/// ```
1870/// # use winnow::prelude::*;
1871/// # use winnow::{error::ErrMode, error::ContextError};
1872/// # use winnow::token::take_while;
1873/// fn hex_digit1<'s>(input: &mut &'s str) -> ModalResult<&'s str, ContextError> {
1874///     take_while(1.., ('a'..='f', 'A'..='F', '0'..='9')).parse_next(input)
1875/// }
1876///
1877/// assert_eq!(hex_digit1.parse_peek("21cZ"), Ok(("Z", "21c")));
1878/// assert!(hex_digit1.parse_peek("H2").is_err());
1879/// assert!(hex_digit1.parse_peek("").is_err());
1880/// ```
1881pub trait ContainsToken<T> {
1882    /// Returns true if self contains the token
1883    fn contains_token(&self, token: T) -> bool;
1884}
1885
1886impl ContainsToken<u8> for u8 {
1887    #[inline(always)]
1888    fn contains_token(&self, token: u8) -> bool {
1889        *self == token
1890    }
1891}
1892
1893impl ContainsToken<&u8> for u8 {
1894    #[inline(always)]
1895    fn contains_token(&self, token: &u8) -> bool {
1896        self.contains_token(*token)
1897    }
1898}
1899
1900impl ContainsToken<char> for u8 {
1901    #[inline(always)]
1902    fn contains_token(&self, token: char) -> bool {
1903        self.as_char() == token
1904    }
1905}
1906
1907impl ContainsToken<&char> for u8 {
1908    #[inline(always)]
1909    fn contains_token(&self, token: &char) -> bool {
1910        self.contains_token(*token)
1911    }
1912}
1913
1914impl<C: AsChar> ContainsToken<C> for char {
1915    #[inline(always)]
1916    fn contains_token(&self, token: C) -> bool {
1917        *self == token.as_char()
1918    }
1919}
1920
1921impl<C, F: Fn(C) -> bool> ContainsToken<C> for F {
1922    #[inline(always)]
1923    fn contains_token(&self, token: C) -> bool {
1924        self(token)
1925    }
1926}
1927
1928impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::Range<C2> {
1929    #[inline(always)]
1930    fn contains_token(&self, token: C1) -> bool {
1931        let start = self.start.clone().as_char();
1932        let end = self.end.clone().as_char();
1933        (start..end).contains(&token.as_char())
1934    }
1935}
1936
1937impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeInclusive<C2> {
1938    #[inline(always)]
1939    fn contains_token(&self, token: C1) -> bool {
1940        let start = self.start().clone().as_char();
1941        let end = self.end().clone().as_char();
1942        (start..=end).contains(&token.as_char())
1943    }
1944}
1945
1946impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeFrom<C2> {
1947    #[inline(always)]
1948    fn contains_token(&self, token: C1) -> bool {
1949        let start = self.start.clone().as_char();
1950        (start..).contains(&token.as_char())
1951    }
1952}
1953
1954impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeTo<C2> {
1955    #[inline(always)]
1956    fn contains_token(&self, token: C1) -> bool {
1957        let end = self.end.clone().as_char();
1958        (..end).contains(&token.as_char())
1959    }
1960}
1961
1962impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeToInclusive<C2> {
1963    #[inline(always)]
1964    fn contains_token(&self, token: C1) -> bool {
1965        let end = self.end.clone().as_char();
1966        (..=end).contains(&token.as_char())
1967    }
1968}
1969
1970impl<C1: AsChar> ContainsToken<C1> for core::ops::RangeFull {
1971    #[inline(always)]
1972    fn contains_token(&self, _token: C1) -> bool {
1973        true
1974    }
1975}
1976
1977impl<C: AsChar> ContainsToken<C> for &'_ [u8] {
1978    #[inline]
1979    fn contains_token(&self, token: C) -> bool {
1980        let token = token.as_char();
1981        self.iter().any(|t| t.as_char() == token)
1982    }
1983}
1984
1985impl<C: AsChar> ContainsToken<C> for &'_ [char] {
1986    #[inline]
1987    fn contains_token(&self, token: C) -> bool {
1988        let token = token.as_char();
1989        self.contains(&token)
1990    }
1991}
1992
1993impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [u8; LEN] {
1994    #[inline]
1995    fn contains_token(&self, token: C) -> bool {
1996        let token = token.as_char();
1997        self.iter().any(|t| t.as_char() == token)
1998    }
1999}
2000
2001impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [char; LEN] {
2002    #[inline]
2003    fn contains_token(&self, token: C) -> bool {
2004        let token = token.as_char();
2005        self.contains(&token)
2006    }
2007}
2008
2009impl<const LEN: usize, C: AsChar> ContainsToken<C> for [u8; LEN] {
2010    #[inline]
2011    fn contains_token(&self, token: C) -> bool {
2012        let token = token.as_char();
2013        self.iter().any(|t| t.as_char() == token)
2014    }
2015}
2016
2017impl<const LEN: usize, C: AsChar> ContainsToken<C> for [char; LEN] {
2018    #[inline]
2019    fn contains_token(&self, token: C) -> bool {
2020        let token = token.as_char();
2021        self.contains(&token)
2022    }
2023}
2024
2025impl<T> ContainsToken<T> for () {
2026    #[inline(always)]
2027    fn contains_token(&self, _token: T) -> bool {
2028        false
2029    }
2030}
2031
2032macro_rules! impl_contains_token_for_tuple {
2033  ($($haystack:ident),+) => (
2034    #[allow(non_snake_case)]
2035    impl<T, $($haystack),+> ContainsToken<T> for ($($haystack),+,)
2036    where
2037    T: Clone,
2038      $($haystack: ContainsToken<T>),+
2039    {
2040    #[inline]
2041      fn contains_token(&self, token: T) -> bool {
2042        let ($(ref $haystack),+,) = *self;
2043        $($haystack.contains_token(token.clone()) || )+ false
2044      }
2045    }
2046  )
2047}
2048
2049macro_rules! impl_contains_token_for_tuples {
2050    ($haystack1:ident, $($haystack:ident),+) => {
2051        impl_contains_token_for_tuples!(__impl $haystack1; $($haystack),+);
2052    };
2053    (__impl $($haystack:ident),+; $haystack1:ident $(,$haystack2:ident)*) => {
2054        impl_contains_token_for_tuple!($($haystack),+);
2055        impl_contains_token_for_tuples!(__impl $($haystack),+, $haystack1; $($haystack2),*);
2056    };
2057    (__impl $($haystack:ident),+;) => {
2058        impl_contains_token_for_tuple!($($haystack),+);
2059    }
2060}
2061
2062impl_contains_token_for_tuples!(
2063    F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21
2064);
2065
2066#[cfg(feature = "simd")]
2067#[inline(always)]
2068fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
2069    memchr::memchr(token, slice)
2070}
2071
2072#[cfg(feature = "simd")]
2073#[inline(always)]
2074fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
2075    memchr::memchr2(token.0, token.1, slice)
2076}
2077
2078#[cfg(feature = "simd")]
2079#[inline(always)]
2080fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
2081    memchr::memchr3(token.0, token.1, token.2, slice)
2082}
2083
2084#[cfg(not(feature = "simd"))]
2085#[inline(always)]
2086fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
2087    slice.iter().position(|t| *t == token)
2088}
2089
2090#[cfg(not(feature = "simd"))]
2091#[inline(always)]
2092fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
2093    slice.iter().position(|t| *t == token.0 || *t == token.1)
2094}
2095
2096#[cfg(not(feature = "simd"))]
2097#[inline(always)]
2098fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
2099    slice
2100        .iter()
2101        .position(|t| *t == token.0 || *t == token.1 || *t == token.2)
2102}
2103
2104#[inline(always)]
2105fn memmem(slice: &[u8], literal: &[u8]) -> Option<core::ops::Range<usize>> {
2106    match literal.len() {
2107        0 => Some(0..0),
2108        1 => memchr(literal[0], slice).map(|i| i..i + 1),
2109        _ => memmem_(slice, literal),
2110    }
2111}
2112
2113#[inline(always)]
2114fn memmem2(slice: &[u8], literal: (&[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2115    match (literal.0.len(), literal.1.len()) {
2116        (0, _) | (_, 0) => Some(0..0),
2117        (1, 1) => memchr2((literal.0[0], literal.1[0]), slice).map(|i| i..i + 1),
2118        _ => memmem2_(slice, literal),
2119    }
2120}
2121
2122#[inline(always)]
2123fn memmem3(slice: &[u8], literal: (&[u8], &[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2124    match (literal.0.len(), literal.1.len(), literal.2.len()) {
2125        (0, _, _) | (_, 0, _) | (_, _, 0) => Some(0..0),
2126        (1, 1, 1) => memchr3((literal.0[0], literal.1[0], literal.2[0]), slice).map(|i| i..i + 1),
2127        _ => memmem3_(slice, literal),
2128    }
2129}
2130
2131#[cfg(feature = "simd")]
2132#[inline(always)]
2133fn memmem_(slice: &[u8], literal: &[u8]) -> Option<core::ops::Range<usize>> {
2134    let &prefix = match literal.first() {
2135        Some(x) => x,
2136        None => return Some(0..0),
2137    };
2138    #[allow(clippy::manual_find)] // faster this way
2139    for i in memchr::memchr_iter(prefix, slice) {
2140        if slice[i..].starts_with(literal) {
2141            let i_end = i + literal.len();
2142            return Some(i..i_end);
2143        }
2144    }
2145    None
2146}
2147
2148#[cfg(feature = "simd")]
2149fn memmem2_(slice: &[u8], literal: (&[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2150    let prefix = match (literal.0.first(), literal.1.first()) {
2151        (Some(&a), Some(&b)) => (a, b),
2152        _ => return Some(0..0),
2153    };
2154    #[allow(clippy::manual_find)] // faster this way
2155    for i in memchr::memchr2_iter(prefix.0, prefix.1, slice) {
2156        let subslice = &slice[i..];
2157        if subslice.starts_with(literal.0) {
2158            let i_end = i + literal.0.len();
2159            return Some(i..i_end);
2160        }
2161        if subslice.starts_with(literal.1) {
2162            let i_end = i + literal.1.len();
2163            return Some(i..i_end);
2164        }
2165    }
2166    None
2167}
2168
2169#[cfg(feature = "simd")]
2170fn memmem3_(slice: &[u8], literal: (&[u8], &[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2171    let prefix = match (literal.0.first(), literal.1.first(), literal.2.first()) {
2172        (Some(&a), Some(&b), Some(&c)) => (a, b, c),
2173        _ => return Some(0..0),
2174    };
2175    #[allow(clippy::manual_find)] // faster this way
2176    for i in memchr::memchr3_iter(prefix.0, prefix.1, prefix.2, slice) {
2177        let subslice = &slice[i..];
2178        if subslice.starts_with(literal.0) {
2179            let i_end = i + literal.0.len();
2180            return Some(i..i_end);
2181        }
2182        if subslice.starts_with(literal.1) {
2183            let i_end = i + literal.1.len();
2184            return Some(i..i_end);
2185        }
2186        if subslice.starts_with(literal.2) {
2187            let i_end = i + literal.2.len();
2188            return Some(i..i_end);
2189        }
2190    }
2191    None
2192}
2193
2194#[cfg(not(feature = "simd"))]
2195fn memmem_(slice: &[u8], literal: &[u8]) -> Option<core::ops::Range<usize>> {
2196    for i in 0..slice.len() {
2197        let subslice = &slice[i..];
2198        if subslice.starts_with(literal) {
2199            let i_end = i + literal.len();
2200            return Some(i..i_end);
2201        }
2202    }
2203    None
2204}
2205
2206#[cfg(not(feature = "simd"))]
2207fn memmem2_(slice: &[u8], literal: (&[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2208    for i in 0..slice.len() {
2209        let subslice = &slice[i..];
2210        if subslice.starts_with(literal.0) {
2211            let i_end = i + literal.0.len();
2212            return Some(i..i_end);
2213        }
2214        if subslice.starts_with(literal.1) {
2215            let i_end = i + literal.1.len();
2216            return Some(i..i_end);
2217        }
2218    }
2219    None
2220}
2221
2222#[cfg(not(feature = "simd"))]
2223fn memmem3_(slice: &[u8], literal: (&[u8], &[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2224    for i in 0..slice.len() {
2225        let subslice = &slice[i..];
2226        if subslice.starts_with(literal.0) {
2227            let i_end = i + literal.0.len();
2228            return Some(i..i_end);
2229        }
2230        if subslice.starts_with(literal.1) {
2231            let i_end = i + literal.1.len();
2232            return Some(i..i_end);
2233        }
2234        if subslice.starts_with(literal.2) {
2235            let i_end = i + literal.2.len();
2236            return Some(i..i_end);
2237        }
2238    }
2239    None
2240}