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