winnow/stream/
mod.rs

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