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