winnow/stream/
mod.rs

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