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//! - [`Located`] 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;
16#[cfg(feature = "unstable-recover")]
17use crate::error::FromRecoverableError;
18use crate::error::Needed;
19use crate::lib::std::iter::{Cloned, Enumerate};
20use crate::lib::std::slice::Iter;
21use crate::lib::std::str::from_utf8;
22use crate::lib::std::str::CharIndices;
23use crate::lib::std::str::FromStr;
24
25#[allow(unused_imports)]
26#[cfg(any(feature = "unstable-doc", feature = "unstable-recover"))]
27use crate::error::ErrMode;
28
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::string::String;
39#[cfg(feature = "alloc")]
40use crate::lib::std::vec::Vec;
41
42mod impls;
43#[cfg(test)]
44mod tests;
45
46/// UTF-8 Stream
47pub type Str<'i> = &'i str;
48
49/// Improved `Debug` experience for `&[u8]` byte streams
50#[allow(clippy::derive_hash_xor_eq)]
51#[derive(Hash)]
52#[repr(transparent)]
53pub struct Bytes([u8]);
54
55impl Bytes {
56 /// Make a stream out of a byte slice-like.
57 #[inline]
58 pub fn new<B: ?Sized + AsRef<[u8]>>(bytes: &B) -> &Self {
59 Self::from_bytes(slice:bytes.as_ref())
60 }
61
62 #[inline]
63 fn from_bytes(slice: &[u8]) -> &Self {
64 unsafe { crate::lib::std::mem::transmute(src:slice) }
65 }
66
67 #[inline]
68 fn as_bytes(&self) -> &[u8] {
69 &self.0
70 }
71}
72
73/// Improved `Debug` experience for `&[u8]` UTF-8-ish streams
74#[allow(clippy::derive_hash_xor_eq)]
75#[derive(Hash)]
76#[repr(transparent)]
77pub struct BStr([u8]);
78
79impl BStr {
80 /// Make a stream out of a byte slice-like.
81 #[inline]
82 pub fn new<B: ?Sized + AsRef<[u8]>>(bytes: &B) -> &Self {
83 Self::from_bytes(slice:bytes.as_ref())
84 }
85
86 #[inline]
87 fn from_bytes(slice: &[u8]) -> &Self {
88 unsafe { crate::lib::std::mem::transmute(src:slice) }
89 }
90
91 #[inline]
92 fn as_bytes(&self) -> &[u8] {
93 &self.0
94 }
95}
96
97/// Allow collecting the span of a parsed token
98///
99/// Spans are tracked as a [`Range<usize>`] of byte offsets.
100///
101/// Converting byte offsets to line or column numbers is left up to the user, as computing column
102/// numbers requires domain knowledge (are columns byte-based, codepoint-based, or grapheme-based?)
103/// and O(n) iteration over the input to determine codepoint and line boundaries.
104///
105/// [The `line-span` crate](https://docs.rs/line-span/latest/line_span/) can help with converting
106/// byte offsets to line numbers.
107///
108/// See [`Parser::span`][crate::Parser::span] and [`Parser::with_span`][crate::Parser::with_span] for more details
109#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
110#[doc(alias = "LocatedSpan")]
111pub struct Located<I> {
112 initial: I,
113 input: I,
114}
115
116impl<I> Located<I>
117where
118 I: Clone + Offset,
119{
120 /// Wrap another Stream with span tracking
121 pub fn new(input: I) -> Self {
122 let initial: I = input.clone();
123 Self { initial, input }
124 }
125
126 fn location(&self) -> usize {
127 self.input.offset_from(&self.initial)
128 }
129}
130
131impl<I> AsRef<I> for Located<I> {
132 #[inline(always)]
133 fn as_ref(&self) -> &I {
134 &self.input
135 }
136}
137
138impl<I> crate::lib::std::ops::Deref for Located<I> {
139 type Target = I;
140
141 #[inline(always)]
142 fn deref(&self) -> &Self::Target {
143 &self.input
144 }
145}
146
147impl<I: crate::lib::std::fmt::Display> crate::lib::std::fmt::Display for Located<I> {
148 fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result {
149 self.input.fmt(f)
150 }
151}
152
153/// Allow recovering from parse errors, capturing them as the parser continues
154///
155/// Generally, this will be used indirectly via
156/// [`RecoverableParser::recoverable_parse`][crate::RecoverableParser::recoverable_parse].
157#[cfg(feature = "unstable-recover")]
158#[derive(Clone, Debug)]
159pub struct Recoverable<I, E>
160where
161 I: Stream,
162{
163 input: I,
164 errors: Vec<E>,
165 is_recoverable: bool,
166}
167
168#[cfg(feature = "unstable-recover")]
169impl<I, E> Recoverable<I, E>
170where
171 I: Stream,
172{
173 /// Track recoverable errors with the stream
174 pub fn new(input: I) -> Self {
175 Self {
176 input,
177 errors: Default::default(),
178 is_recoverable: true,
179 }
180 }
181
182 /// Act as a normal stream
183 pub fn unrecoverable(input: I) -> Self {
184 Self {
185 input,
186 errors: Default::default(),
187 is_recoverable: false,
188 }
189 }
190
191 /// Access the current input and errors
192 pub fn into_parts(self) -> (I, Vec<E>) {
193 (self.input, self.errors)
194 }
195}
196
197#[cfg(feature = "unstable-recover")]
198impl<I, E> AsRef<I> for Recoverable<I, E>
199where
200 I: Stream,
201{
202 #[inline(always)]
203 fn as_ref(&self) -> &I {
204 &self.input
205 }
206}
207
208#[cfg(feature = "unstable-recover")]
209impl<I, E> crate::lib::std::ops::Deref for Recoverable<I, E>
210where
211 I: Stream,
212{
213 type Target = I;
214
215 #[inline(always)]
216 fn deref(&self) -> &Self::Target {
217 &self.input
218 }
219}
220
221#[cfg(feature = "unstable-recover")]
222impl<I: crate::lib::std::fmt::Display, E> crate::lib::std::fmt::Display for Recoverable<I, E>
223where
224 I: Stream,
225{
226 fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result {
227 crate::lib::std::fmt::Display::fmt(&self.input, f)
228 }
229}
230
231/// Thread global state through your parsers
232///
233/// Use cases
234/// - Recursion checks
235/// - Error recovery
236/// - Debugging
237///
238/// # Example
239///
240/// ```
241/// # use std::cell::Cell;
242/// # use winnow::prelude::*;
243/// # use winnow::stream::Stateful;
244/// # use winnow::ascii::alpha1;
245/// # type Error = ();
246///
247/// #[derive(Clone, Debug)]
248/// struct State<'s>(&'s Cell<u32>);
249///
250/// impl<'s> State<'s> {
251/// fn count(&self) {
252/// self.0.set(self.0.get() + 1);
253/// }
254/// }
255///
256/// type Stream<'is> = Stateful<&'is str, State<'is>>;
257///
258/// fn word<'s>(i: &mut Stream<'s>) -> PResult<&'s str> {
259/// i.state.count();
260/// alpha1.parse_next(i)
261/// }
262///
263/// let data = "Hello";
264/// let state = Cell::new(0);
265/// let input = Stream { input: data, state: State(&state) };
266/// let output = word.parse(input).unwrap();
267/// assert_eq!(state.get(), 1);
268/// ```
269#[derive(Clone, Copy, Debug, Eq, PartialEq)]
270#[doc(alias = "LocatedSpan")]
271pub struct Stateful<I, S> {
272 /// Inner input being wrapped in state
273 pub input: I,
274 /// User-provided state
275 pub state: S,
276}
277
278impl<I, S> AsRef<I> for Stateful<I, S> {
279 #[inline(always)]
280 fn as_ref(&self) -> &I {
281 &self.input
282 }
283}
284
285impl<I, S> crate::lib::std::ops::Deref for Stateful<I, S> {
286 type Target = I;
287
288 #[inline(always)]
289 fn deref(&self) -> &Self::Target {
290 self.as_ref()
291 }
292}
293
294impl<I: crate::lib::std::fmt::Display, S> crate::lib::std::fmt::Display for Stateful<I, S> {
295 fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result {
296 self.input.fmt(f)
297 }
298}
299
300/// Mark the input as a partial buffer for streaming input.
301///
302/// Complete input means that we already have all of the data. This will be the common case with
303/// small files that can be read entirely to memory.
304///
305/// In contrast, streaming input assumes that we might not have all of the data.
306/// This can happen with some network protocol or large file parsers, where the
307/// input buffer can be full and need to be resized or refilled.
308/// - [`ErrMode::Incomplete`] will report how much more data is needed.
309/// - [`Parser::complete_err`][crate::Parser::complete_err] transform [`ErrMode::Incomplete`] to
310/// [`ErrMode::Backtrack`]
311///
312/// See also [`StreamIsPartial`] to tell whether the input supports complete or partial parsing.
313///
314/// See also [Special Topics: Parsing Partial Input][crate::_topic::partial].
315///
316/// # Example
317///
318/// Here is how it works in practice:
319///
320/// ```rust
321/// # use winnow::{PResult, error::ErrMode, error::Needed, error::{InputError, ErrorKind}, token, ascii, stream::Partial};
322/// # use winnow::prelude::*;
323///
324/// fn take_partial<'s>(i: &mut Partial<&'s [u8]>) -> PResult<&'s [u8], InputError<Partial<&'s [u8]>>> {
325/// token::take(4u8).parse_next(i)
326/// }
327///
328/// fn take_complete<'s>(i: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> {
329/// token::take(4u8).parse_next(i)
330/// }
331///
332/// // both parsers will take 4 bytes as expected
333/// assert_eq!(take_partial.parse_peek(Partial::new(&b"abcde"[..])), Ok((Partial::new(&b"e"[..]), &b"abcd"[..])));
334/// assert_eq!(take_complete.parse_peek(&b"abcde"[..]), Ok((&b"e"[..], &b"abcd"[..])));
335///
336/// // if the input is smaller than 4 bytes, the partial parser
337/// // will return `Incomplete` to indicate that we need more data
338/// assert_eq!(take_partial.parse_peek(Partial::new(&b"abc"[..])), Err(ErrMode::Incomplete(Needed::new(1))));
339///
340/// // but the complete parser will return an error
341/// assert_eq!(take_complete.parse_peek(&b"abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"abc"[..], ErrorKind::Slice))));
342///
343/// // the alpha0 function recognizes 0 or more alphabetic characters
344/// fn alpha0_partial<'s>(i: &mut Partial<&'s str>) -> PResult<&'s str, InputError<Partial<&'s str>>> {
345/// ascii::alpha0.parse_next(i)
346/// }
347///
348/// fn alpha0_complete<'s>(i: &mut &'s str) -> PResult<&'s str, InputError<&'s str>> {
349/// ascii::alpha0.parse_next(i)
350/// }
351///
352/// // if there's a clear limit to the recognized characters, both parsers work the same way
353/// assert_eq!(alpha0_partial.parse_peek(Partial::new("abcd;")), Ok((Partial::new(";"), "abcd")));
354/// assert_eq!(alpha0_complete.parse_peek("abcd;"), Ok((";", "abcd")));
355///
356/// // but when there's no limit, the partial version returns `Incomplete`, because it cannot
357/// // know if more input data should be recognized. The whole input could be "abcd;", or
358/// // "abcde;"
359/// assert_eq!(alpha0_partial.parse_peek(Partial::new("abcd")), Err(ErrMode::Incomplete(Needed::new(1))));
360///
361/// // while the complete version knows that all of the data is there
362/// assert_eq!(alpha0_complete.parse_peek("abcd"), Ok(("", "abcd")));
363/// ```
364#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
365pub struct Partial<I> {
366 input: I,
367 partial: bool,
368}
369
370impl<I> Partial<I>
371where
372 I: StreamIsPartial,
373{
374 /// Create a partial input
375 pub fn new(input: I) -> Self {
376 debug_assert!(
377 !I::is_partial_supported(),
378 "`Partial` can only wrap complete sources"
379 );
380 let partial: bool = true;
381 Self { input, partial }
382 }
383
384 /// Extract the original [`Stream`]
385 #[inline(always)]
386 pub fn into_inner(self) -> I {
387 self.input
388 }
389}
390
391impl<I> Default for Partial<I>
392where
393 I: Default + StreamIsPartial,
394{
395 fn default() -> Self {
396 Self::new(I::default())
397 }
398}
399
400impl<I> crate::lib::std::ops::Deref for Partial<I> {
401 type Target = I;
402
403 #[inline(always)]
404 fn deref(&self) -> &Self::Target {
405 &self.input
406 }
407}
408
409impl<I: crate::lib::std::fmt::Display> crate::lib::std::fmt::Display for Partial<I> {
410 fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result {
411 self.input.fmt(f)
412 }
413}
414
415/// Abstract method to calculate the input length
416pub trait SliceLen {
417 /// Calculates the input length, as indicated by its name,
418 /// and the name of the trait itself
419 fn slice_len(&self) -> usize;
420}
421
422impl<S: SliceLen> SliceLen for AsciiCaseless<S> {
423 #[inline(always)]
424 fn slice_len(&self) -> usize {
425 self.0.slice_len()
426 }
427}
428
429impl<'a, T> SliceLen for &'a [T] {
430 #[inline(always)]
431 fn slice_len(&self) -> usize {
432 self.len()
433 }
434}
435
436impl<T, const LEN: usize> SliceLen for [T; LEN] {
437 #[inline(always)]
438 fn slice_len(&self) -> usize {
439 self.len()
440 }
441}
442
443impl<'a, T, const LEN: usize> SliceLen for &'a [T; LEN] {
444 #[inline(always)]
445 fn slice_len(&self) -> usize {
446 self.len()
447 }
448}
449
450impl<'a> SliceLen for &'a str {
451 #[inline(always)]
452 fn slice_len(&self) -> usize {
453 self.len()
454 }
455}
456
457impl SliceLen for u8 {
458 #[inline(always)]
459 fn slice_len(&self) -> usize {
460 1
461 }
462}
463
464impl SliceLen for char {
465 #[inline(always)]
466 fn slice_len(&self) -> usize {
467 self.len_utf8()
468 }
469}
470
471impl<'a> SliceLen for &'a Bytes {
472 #[inline(always)]
473 fn slice_len(&self) -> usize {
474 self.len()
475 }
476}
477
478impl<'a> SliceLen for &'a BStr {
479 #[inline(always)]
480 fn slice_len(&self) -> usize {
481 self.len()
482 }
483}
484
485impl<I> SliceLen for (I, usize, usize)
486where
487 I: SliceLen,
488{
489 #[inline(always)]
490 fn slice_len(&self) -> usize {
491 self.0.slice_len() * 8 + self.2 - self.1
492 }
493}
494
495impl<I> SliceLen for Located<I>
496where
497 I: SliceLen,
498{
499 #[inline(always)]
500 fn slice_len(&self) -> usize {
501 self.input.slice_len()
502 }
503}
504
505#[cfg(feature = "unstable-recover")]
506impl<I, E> SliceLen for Recoverable<I, E>
507where
508 I: SliceLen,
509 I: Stream,
510{
511 #[inline(always)]
512 fn slice_len(&self) -> usize {
513 self.input.slice_len()
514 }
515}
516
517impl<I, S> SliceLen for Stateful<I, S>
518where
519 I: SliceLen,
520{
521 #[inline(always)]
522 fn slice_len(&self) -> usize {
523 self.input.slice_len()
524 }
525}
526
527impl<I> SliceLen for Partial<I>
528where
529 I: SliceLen,
530{
531 #[inline(always)]
532 fn slice_len(&self) -> usize {
533 self.input.slice_len()
534 }
535}
536
537/// Core definition for parser input state
538pub trait Stream: Offset<<Self as Stream>::Checkpoint> + crate::lib::std::fmt::Debug {
539 /// The smallest unit being parsed
540 ///
541 /// Example: `u8` for `&[u8]` or `char` for `&str`
542 type Token: crate::lib::std::fmt::Debug;
543 /// Sequence of `Token`s
544 ///
545 /// Example: `&[u8]` for `Located<&[u8]>` or `&str` for `Located<&str>`
546 type Slice: crate::lib::std::fmt::Debug;
547
548 /// Iterate with the offset from the current location
549 type IterOffsets: Iterator<Item = (usize, Self::Token)>;
550
551 /// A parse location within the stream
552 type Checkpoint: Offset + Clone + crate::lib::std::fmt::Debug;
553
554 /// Iterate with the offset from the current location
555 fn iter_offsets(&self) -> Self::IterOffsets;
556
557 /// Returns the offset to the end of the input
558 fn eof_offset(&self) -> usize;
559
560 /// Split off the next token from the input
561 fn next_token(&mut self) -> Option<Self::Token>;
562 /// Split off the next token from the input
563 #[inline(always)]
564 fn peek_token(&self) -> Option<(Self, Self::Token)>
565 where
566 Self: Clone,
567 {
568 let mut peek = self.clone();
569 let token = peek.next_token()?;
570 Some((peek, token))
571 }
572
573 /// Finds the offset of the next matching token
574 fn offset_for<P>(&self, predicate: P) -> Option<usize>
575 where
576 P: Fn(Self::Token) -> bool;
577 /// Get the offset for the number of `tokens` into the stream
578 ///
579 /// This means "0 tokens" will return `0` offset
580 fn offset_at(&self, tokens: usize) -> Result<usize, Needed>;
581 /// Split off a slice of tokens from the input
582 ///
583 /// **NOTE:** For inputs with variable width tokens, like `&str`'s `char`, `offset` might not correspond
584 /// with the number of tokens. To get a valid offset, use:
585 /// - [`Stream::eof_offset`]
586 /// - [`Stream::iter_offsets`]
587 /// - [`Stream::offset_for`]
588 /// - [`Stream::offset_at`]
589 ///
590 /// # Panic
591 ///
592 /// This will panic if
593 ///
594 /// * Indexes must be within bounds of the original input;
595 /// * Indexes must uphold invariants of the stream, like for `str` they must lie on UTF-8
596 /// sequence boundaries.
597 ///
598 fn next_slice(&mut self, offset: usize) -> Self::Slice;
599 /// Split off a slice of tokens from the input
600 #[inline(always)]
601 fn peek_slice(&self, offset: usize) -> (Self, Self::Slice)
602 where
603 Self: Clone,
604 {
605 let mut peek = self.clone();
606 let slice = peek.next_slice(offset);
607 (peek, slice)
608 }
609
610 /// Advance to the end of the stream
611 #[inline(always)]
612 fn finish(&mut self) -> Self::Slice {
613 self.next_slice(self.eof_offset())
614 }
615 /// Advance to the end of the stream
616 #[inline(always)]
617 fn peek_finish(&self) -> (Self, Self::Slice)
618 where
619 Self: Clone,
620 {
621 let mut peek = self.clone();
622 let slice = peek.finish();
623 (peek, slice)
624 }
625
626 /// Save the current parse location within the stream
627 fn checkpoint(&self) -> Self::Checkpoint;
628 /// Revert the stream to a prior [`Self::Checkpoint`]
629 ///
630 /// # Panic
631 ///
632 /// May panic if an invalid [`Self::Checkpoint`] is provided
633 fn reset(&mut self, checkpoint: Self::Checkpoint);
634
635 /// Return the inner-most stream
636 fn raw(&self) -> &dyn crate::lib::std::fmt::Debug;
637}
638
639impl<'i, T> Stream for &'i [T]
640where
641 T: Clone + crate::lib::std::fmt::Debug,
642{
643 type Token = T;
644 type Slice = &'i [T];
645
646 type IterOffsets = Enumerate<Cloned<Iter<'i, T>>>;
647
648 type Checkpoint = Checkpoint<Self>;
649
650 #[inline(always)]
651 fn iter_offsets(&self) -> Self::IterOffsets {
652 self.iter().cloned().enumerate()
653 }
654 #[inline(always)]
655 fn eof_offset(&self) -> usize {
656 self.len()
657 }
658
659 #[inline(always)]
660 fn next_token(&mut self) -> Option<Self::Token> {
661 let (token, next) = self.split_first()?;
662 *self = next;
663 Some(token.clone())
664 }
665
666 #[inline(always)]
667 fn offset_for<P>(&self, predicate: P) -> Option<usize>
668 where
669 P: Fn(Self::Token) -> bool,
670 {
671 self.iter().position(|b| predicate(b.clone()))
672 }
673 #[inline(always)]
674 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
675 if let Some(needed) = tokens.checked_sub(self.len()).and_then(NonZeroUsize::new) {
676 Err(Needed::Size(needed))
677 } else {
678 Ok(tokens)
679 }
680 }
681 #[inline(always)]
682 fn next_slice(&mut self, offset: usize) -> Self::Slice {
683 let (slice, next) = self.split_at(offset);
684 *self = next;
685 slice
686 }
687
688 #[inline(always)]
689 fn checkpoint(&self) -> Self::Checkpoint {
690 Checkpoint(*self)
691 }
692 #[inline(always)]
693 fn reset(&mut self, checkpoint: Self::Checkpoint) {
694 *self = checkpoint.0;
695 }
696
697 #[inline(always)]
698 fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
699 self
700 }
701}
702
703impl<'i> Stream for &'i str {
704 type Token = char;
705 type Slice = &'i str;
706
707 type IterOffsets = CharIndices<'i>;
708
709 type Checkpoint = Checkpoint<Self>;
710
711 #[inline(always)]
712 fn iter_offsets(&self) -> Self::IterOffsets {
713 self.char_indices()
714 }
715 #[inline(always)]
716 fn eof_offset(&self) -> usize {
717 self.len()
718 }
719
720 #[inline(always)]
721 fn next_token(&mut self) -> Option<Self::Token> {
722 let c = self.chars().next()?;
723 let offset = c.len();
724 *self = &self[offset..];
725 Some(c)
726 }
727
728 #[inline(always)]
729 fn offset_for<P>(&self, predicate: P) -> Option<usize>
730 where
731 P: Fn(Self::Token) -> bool,
732 {
733 for (o, c) in self.iter_offsets() {
734 if predicate(c) {
735 return Some(o);
736 }
737 }
738 None
739 }
740 #[inline]
741 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
742 let mut cnt = 0;
743 for (offset, _) in self.iter_offsets() {
744 if cnt == tokens {
745 return Ok(offset);
746 }
747 cnt += 1;
748 }
749
750 if cnt == tokens {
751 Ok(self.eof_offset())
752 } else {
753 Err(Needed::Unknown)
754 }
755 }
756 #[inline(always)]
757 fn next_slice(&mut self, offset: usize) -> Self::Slice {
758 let (slice, next) = self.split_at(offset);
759 *self = next;
760 slice
761 }
762
763 #[inline(always)]
764 fn checkpoint(&self) -> Self::Checkpoint {
765 Checkpoint(*self)
766 }
767 #[inline(always)]
768 fn reset(&mut self, checkpoint: Self::Checkpoint) {
769 *self = checkpoint.0;
770 }
771
772 #[inline(always)]
773 fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
774 self
775 }
776}
777
778impl<'i> Stream for &'i Bytes {
779 type Token = u8;
780 type Slice = &'i [u8];
781
782 type IterOffsets = Enumerate<Cloned<Iter<'i, u8>>>;
783
784 type Checkpoint = Checkpoint<Self>;
785
786 #[inline(always)]
787 fn iter_offsets(&self) -> Self::IterOffsets {
788 self.iter().cloned().enumerate()
789 }
790 #[inline(always)]
791 fn eof_offset(&self) -> usize {
792 self.len()
793 }
794
795 #[inline(always)]
796 fn next_token(&mut self) -> Option<Self::Token> {
797 if self.is_empty() {
798 None
799 } else {
800 let token = self[0];
801 *self = &self[1..];
802 Some(token)
803 }
804 }
805
806 #[inline(always)]
807 fn offset_for<P>(&self, predicate: P) -> Option<usize>
808 where
809 P: Fn(Self::Token) -> bool,
810 {
811 self.iter().position(|b| predicate(*b))
812 }
813 #[inline(always)]
814 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
815 if let Some(needed) = tokens.checked_sub(self.len()).and_then(NonZeroUsize::new) {
816 Err(Needed::Size(needed))
817 } else {
818 Ok(tokens)
819 }
820 }
821 #[inline(always)]
822 fn next_slice(&mut self, offset: usize) -> Self::Slice {
823 let (slice, next) = self.0.split_at(offset);
824 *self = Bytes::from_bytes(next);
825 slice
826 }
827
828 #[inline(always)]
829 fn checkpoint(&self) -> Self::Checkpoint {
830 Checkpoint(*self)
831 }
832 #[inline(always)]
833 fn reset(&mut self, checkpoint: Self::Checkpoint) {
834 *self = checkpoint.0;
835 }
836
837 #[inline(always)]
838 fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
839 self
840 }
841}
842
843impl<'i> Stream for &'i BStr {
844 type Token = u8;
845 type Slice = &'i [u8];
846
847 type IterOffsets = Enumerate<Cloned<Iter<'i, u8>>>;
848
849 type Checkpoint = Checkpoint<Self>;
850
851 #[inline(always)]
852 fn iter_offsets(&self) -> Self::IterOffsets {
853 self.iter().cloned().enumerate()
854 }
855 #[inline(always)]
856 fn eof_offset(&self) -> usize {
857 self.len()
858 }
859
860 #[inline(always)]
861 fn next_token(&mut self) -> Option<Self::Token> {
862 if self.is_empty() {
863 None
864 } else {
865 let token = self[0];
866 *self = &self[1..];
867 Some(token)
868 }
869 }
870
871 #[inline(always)]
872 fn offset_for<P>(&self, predicate: P) -> Option<usize>
873 where
874 P: Fn(Self::Token) -> bool,
875 {
876 self.iter().position(|b| predicate(*b))
877 }
878 #[inline(always)]
879 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
880 if let Some(needed) = tokens.checked_sub(self.len()).and_then(NonZeroUsize::new) {
881 Err(Needed::Size(needed))
882 } else {
883 Ok(tokens)
884 }
885 }
886 #[inline(always)]
887 fn next_slice(&mut self, offset: usize) -> Self::Slice {
888 let (slice, next) = self.0.split_at(offset);
889 *self = BStr::from_bytes(next);
890 slice
891 }
892
893 #[inline(always)]
894 fn checkpoint(&self) -> Self::Checkpoint {
895 Checkpoint(*self)
896 }
897 #[inline(always)]
898 fn reset(&mut self, checkpoint: Self::Checkpoint) {
899 *self = checkpoint.0;
900 }
901
902 #[inline(always)]
903 fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
904 self
905 }
906}
907
908impl<I> Stream for (I, usize)
909where
910 I: Stream<Token = u8> + Clone,
911{
912 type Token = bool;
913 type Slice = (I::Slice, usize, usize);
914
915 type IterOffsets = BitOffsets<I>;
916
917 type Checkpoint = Checkpoint<(I::Checkpoint, usize)>;
918
919 #[inline(always)]
920 fn iter_offsets(&self) -> Self::IterOffsets {
921 BitOffsets {
922 i: self.clone(),
923 o: 0,
924 }
925 }
926 #[inline(always)]
927 fn eof_offset(&self) -> usize {
928 let offset = self.0.eof_offset() * 8;
929 if offset == 0 {
930 0
931 } else {
932 offset - self.1
933 }
934 }
935
936 #[inline(always)]
937 fn next_token(&mut self) -> Option<Self::Token> {
938 next_bit(self)
939 }
940
941 #[inline(always)]
942 fn offset_for<P>(&self, predicate: P) -> Option<usize>
943 where
944 P: Fn(Self::Token) -> bool,
945 {
946 self.iter_offsets()
947 .find_map(|(o, b)| predicate(b).then_some(o))
948 }
949 #[inline(always)]
950 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
951 if let Some(needed) = tokens
952 .checked_sub(self.eof_offset())
953 .and_then(NonZeroUsize::new)
954 {
955 Err(Needed::Size(needed))
956 } else {
957 Ok(tokens)
958 }
959 }
960 #[inline(always)]
961 fn next_slice(&mut self, offset: usize) -> Self::Slice {
962 let byte_offset = (offset + self.1) / 8;
963 let end_offset = (offset + self.1) % 8;
964 let s = self.0.next_slice(byte_offset);
965 let start_offset = self.1;
966 self.1 = end_offset;
967 (s, start_offset, end_offset)
968 }
969
970 #[inline(always)]
971 fn checkpoint(&self) -> Self::Checkpoint {
972 Checkpoint((self.0.checkpoint(), self.1))
973 }
974 #[inline(always)]
975 fn reset(&mut self, checkpoint: Self::Checkpoint) {
976 self.0.reset(checkpoint.0 .0);
977 self.1 = checkpoint.0 .1;
978 }
979
980 #[inline(always)]
981 fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
982 &self.0
983 }
984}
985
986/// Iterator for [bit][crate::binary::bits] stream (`(I, usize)`)
987pub struct BitOffsets<I> {
988 i: (I, usize),
989 o: usize,
990}
991
992impl<I> Iterator for BitOffsets<I>
993where
994 I: Stream<Token = u8> + Clone,
995{
996 type Item = (usize, bool);
997 fn next(&mut self) -> Option<Self::Item> {
998 let b: bool = next_bit(&mut self.i)?;
999 let o: usize = self.o;
1000
1001 self.o += 1;
1002
1003 Some((o, b))
1004 }
1005}
1006
1007fn next_bit<I>(i: &mut (I, usize)) -> Option<bool>
1008where
1009 I: Stream<Token = u8> + Clone,
1010{
1011 if i.eof_offset() == 0 {
1012 return None;
1013 }
1014 let offset: usize = i.1;
1015
1016 let mut next_i: I = i.0.clone();
1017 let byte: u8 = next_i.next_token()?;
1018 let bit: bool = (byte >> offset) & 0x1 == 0x1;
1019
1020 let next_offset: usize = offset + 1;
1021 if next_offset == 8 {
1022 i.0 = next_i;
1023 i.1 = 0;
1024 Some(bit)
1025 } else {
1026 i.1 = next_offset;
1027 Some(bit)
1028 }
1029}
1030
1031impl<I: Stream> Stream for Located<I> {
1032 type Token = <I as Stream>::Token;
1033 type Slice = <I as Stream>::Slice;
1034
1035 type IterOffsets = <I as Stream>::IterOffsets;
1036
1037 type Checkpoint = Checkpoint<I::Checkpoint>;
1038
1039 #[inline(always)]
1040 fn iter_offsets(&self) -> Self::IterOffsets {
1041 self.input.iter_offsets()
1042 }
1043 #[inline(always)]
1044 fn eof_offset(&self) -> usize {
1045 self.input.eof_offset()
1046 }
1047
1048 #[inline(always)]
1049 fn next_token(&mut self) -> Option<Self::Token> {
1050 self.input.next_token()
1051 }
1052
1053 #[inline(always)]
1054 fn offset_for<P>(&self, predicate: P) -> Option<usize>
1055 where
1056 P: Fn(Self::Token) -> bool,
1057 {
1058 self.input.offset_for(predicate)
1059 }
1060 #[inline(always)]
1061 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
1062 self.input.offset_at(tokens)
1063 }
1064 #[inline(always)]
1065 fn next_slice(&mut self, offset: usize) -> Self::Slice {
1066 self.input.next_slice(offset)
1067 }
1068
1069 #[inline(always)]
1070 fn checkpoint(&self) -> Self::Checkpoint {
1071 Checkpoint(self.input.checkpoint())
1072 }
1073 #[inline(always)]
1074 fn reset(&mut self, checkpoint: Self::Checkpoint) {
1075 self.input.reset(checkpoint.0);
1076 }
1077
1078 #[inline(always)]
1079 fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
1080 &self.input
1081 }
1082}
1083
1084#[cfg(feature = "unstable-recover")]
1085impl<I, E: crate::lib::std::fmt::Debug> Stream for Recoverable<I, E>
1086where
1087 I: Stream,
1088{
1089 type Token = <I as Stream>::Token;
1090 type Slice = <I as Stream>::Slice;
1091
1092 type IterOffsets = <I as Stream>::IterOffsets;
1093
1094 type Checkpoint = Checkpoint<I::Checkpoint>;
1095
1096 #[inline(always)]
1097 fn iter_offsets(&self) -> Self::IterOffsets {
1098 self.input.iter_offsets()
1099 }
1100 #[inline(always)]
1101 fn eof_offset(&self) -> usize {
1102 self.input.eof_offset()
1103 }
1104
1105 #[inline(always)]
1106 fn next_token(&mut self) -> Option<Self::Token> {
1107 self.input.next_token()
1108 }
1109
1110 #[inline(always)]
1111 fn offset_for<P>(&self, predicate: P) -> Option<usize>
1112 where
1113 P: Fn(Self::Token) -> bool,
1114 {
1115 self.input.offset_for(predicate)
1116 }
1117 #[inline(always)]
1118 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
1119 self.input.offset_at(tokens)
1120 }
1121 #[inline(always)]
1122 fn next_slice(&mut self, offset: usize) -> Self::Slice {
1123 self.input.next_slice(offset)
1124 }
1125
1126 #[inline(always)]
1127 fn checkpoint(&self) -> Self::Checkpoint {
1128 Checkpoint(self.input.checkpoint())
1129 }
1130 #[inline(always)]
1131 fn reset(&mut self, checkpoint: Self::Checkpoint) {
1132 self.input.reset(checkpoint.0);
1133 }
1134
1135 #[inline(always)]
1136 fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
1137 &self.input
1138 }
1139}
1140
1141impl<I: Stream, S: crate::lib::std::fmt::Debug> Stream for Stateful<I, S> {
1142 type Token = <I as Stream>::Token;
1143 type Slice = <I as Stream>::Slice;
1144
1145 type IterOffsets = <I as Stream>::IterOffsets;
1146
1147 type Checkpoint = Checkpoint<I::Checkpoint>;
1148
1149 #[inline(always)]
1150 fn iter_offsets(&self) -> Self::IterOffsets {
1151 self.input.iter_offsets()
1152 }
1153 #[inline(always)]
1154 fn eof_offset(&self) -> usize {
1155 self.input.eof_offset()
1156 }
1157
1158 #[inline(always)]
1159 fn next_token(&mut self) -> Option<Self::Token> {
1160 self.input.next_token()
1161 }
1162
1163 #[inline(always)]
1164 fn offset_for<P>(&self, predicate: P) -> Option<usize>
1165 where
1166 P: Fn(Self::Token) -> bool,
1167 {
1168 self.input.offset_for(predicate)
1169 }
1170 #[inline(always)]
1171 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
1172 self.input.offset_at(tokens)
1173 }
1174 #[inline(always)]
1175 fn next_slice(&mut self, offset: usize) -> Self::Slice {
1176 self.input.next_slice(offset)
1177 }
1178
1179 #[inline(always)]
1180 fn checkpoint(&self) -> Self::Checkpoint {
1181 Checkpoint(self.input.checkpoint())
1182 }
1183 #[inline(always)]
1184 fn reset(&mut self, checkpoint: Self::Checkpoint) {
1185 self.input.reset(checkpoint.0);
1186 }
1187
1188 #[inline(always)]
1189 fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
1190 &self.input
1191 }
1192}
1193
1194impl<I: Stream> Stream for Partial<I> {
1195 type Token = <I as Stream>::Token;
1196 type Slice = <I as Stream>::Slice;
1197
1198 type IterOffsets = <I as Stream>::IterOffsets;
1199
1200 type Checkpoint = Checkpoint<I::Checkpoint>;
1201
1202 #[inline(always)]
1203 fn iter_offsets(&self) -> Self::IterOffsets {
1204 self.input.iter_offsets()
1205 }
1206 #[inline(always)]
1207 fn eof_offset(&self) -> usize {
1208 self.input.eof_offset()
1209 }
1210
1211 #[inline(always)]
1212 fn next_token(&mut self) -> Option<Self::Token> {
1213 self.input.next_token()
1214 }
1215
1216 #[inline(always)]
1217 fn offset_for<P>(&self, predicate: P) -> Option<usize>
1218 where
1219 P: Fn(Self::Token) -> bool,
1220 {
1221 self.input.offset_for(predicate)
1222 }
1223 #[inline(always)]
1224 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
1225 self.input.offset_at(tokens)
1226 }
1227 #[inline(always)]
1228 fn next_slice(&mut self, offset: usize) -> Self::Slice {
1229 self.input.next_slice(offset)
1230 }
1231
1232 #[inline(always)]
1233 fn checkpoint(&self) -> Self::Checkpoint {
1234 Checkpoint(self.input.checkpoint())
1235 }
1236 #[inline(always)]
1237 fn reset(&mut self, checkpoint: Self::Checkpoint) {
1238 self.input.reset(checkpoint.0);
1239 }
1240
1241 #[inline(always)]
1242 fn raw(&self) -> &dyn crate::lib::std::fmt::Debug {
1243 &self.input
1244 }
1245}
1246
1247/// Number of indices input has advanced since start of parsing
1248///
1249/// See [`Located`] for adding location tracking to your [`Stream`]
1250pub trait Location {
1251 /// Number of indices input has advanced since start of parsing
1252 fn location(&self) -> usize;
1253}
1254
1255impl<I> Location for Located<I>
1256where
1257 I: Clone + Offset,
1258{
1259 #[inline(always)]
1260 fn location(&self) -> usize {
1261 self.location()
1262 }
1263}
1264
1265#[cfg(feature = "unstable-recover")]
1266impl<I, E> Location for Recoverable<I, E>
1267where
1268 I: Location,
1269 I: Stream,
1270{
1271 #[inline(always)]
1272 fn location(&self) -> usize {
1273 self.input.location()
1274 }
1275}
1276
1277impl<I, S> Location for Stateful<I, S>
1278where
1279 I: Location,
1280{
1281 #[inline(always)]
1282 fn location(&self) -> usize {
1283 self.input.location()
1284 }
1285}
1286
1287impl<I> Location for Partial<I>
1288where
1289 I: Location,
1290{
1291 #[inline(always)]
1292 fn location(&self) -> usize {
1293 self.input.location()
1294 }
1295}
1296
1297/// Capture top-level errors in the middle of parsing so parsing can resume
1298///
1299/// See [`Recoverable`] for adding error recovery tracking to your [`Stream`]
1300#[cfg(feature = "unstable-recover")]
1301pub trait Recover<E>: Stream {
1302 /// Capture a top-level error
1303 ///
1304 /// May return `Err(err)` if recovery is not possible (e.g. if [`Recover::is_recovery_supported`]
1305 /// returns `false`).
1306 fn record_err(
1307 &mut self,
1308 token_start: &Self::Checkpoint,
1309 err_start: &Self::Checkpoint,
1310 err: ErrMode<E>,
1311 ) -> Result<(), ErrMode<E>>;
1312
1313 /// Report whether the [`Stream`] can save off errors for recovery
1314 fn is_recovery_supported() -> bool;
1315}
1316
1317#[cfg(feature = "unstable-recover")]
1318impl<'a, T, E> Recover<E> for &'a [T]
1319where
1320 &'a [T]: Stream,
1321{
1322 #[inline(always)]
1323 fn record_err(
1324 &mut self,
1325 _token_start: &Self::Checkpoint,
1326 _err_start: &Self::Checkpoint,
1327 err: ErrMode<E>,
1328 ) -> Result<(), ErrMode<E>> {
1329 Err(err)
1330 }
1331
1332 /// Report whether the [`Stream`] can save off errors for recovery
1333 #[inline(always)]
1334 fn is_recovery_supported() -> bool {
1335 false
1336 }
1337}
1338
1339#[cfg(feature = "unstable-recover")]
1340impl<'a, E> Recover<E> for &'a str {
1341 #[inline(always)]
1342 fn record_err(
1343 &mut self,
1344 _token_start: &Self::Checkpoint,
1345 _err_start: &Self::Checkpoint,
1346 err: ErrMode<E>,
1347 ) -> Result<(), ErrMode<E>> {
1348 Err(err)
1349 }
1350
1351 /// Report whether the [`Stream`] can save off errors for recovery
1352 #[inline(always)]
1353 fn is_recovery_supported() -> bool {
1354 false
1355 }
1356}
1357
1358#[cfg(feature = "unstable-recover")]
1359impl<'a, E> Recover<E> for &'a Bytes {
1360 #[inline(always)]
1361 fn record_err(
1362 &mut self,
1363 _token_start: &Self::Checkpoint,
1364 _err_start: &Self::Checkpoint,
1365 err: ErrMode<E>,
1366 ) -> Result<(), ErrMode<E>> {
1367 Err(err)
1368 }
1369
1370 /// Report whether the [`Stream`] can save off errors for recovery
1371 #[inline(always)]
1372 fn is_recovery_supported() -> bool {
1373 false
1374 }
1375}
1376
1377#[cfg(feature = "unstable-recover")]
1378impl<'a, E> Recover<E> for &'a BStr {
1379 #[inline(always)]
1380 fn record_err(
1381 &mut self,
1382 _token_start: &Self::Checkpoint,
1383 _err_start: &Self::Checkpoint,
1384 err: ErrMode<E>,
1385 ) -> Result<(), ErrMode<E>> {
1386 Err(err)
1387 }
1388
1389 /// Report whether the [`Stream`] can save off errors for recovery
1390 #[inline(always)]
1391 fn is_recovery_supported() -> bool {
1392 false
1393 }
1394}
1395
1396#[cfg(feature = "unstable-recover")]
1397impl<I, E> Recover<E> for (I, usize)
1398where
1399 I: Recover<E>,
1400 I: Stream<Token = u8> + Clone,
1401{
1402 #[inline(always)]
1403 fn record_err(
1404 &mut self,
1405 _token_start: &Self::Checkpoint,
1406 _err_start: &Self::Checkpoint,
1407 err: ErrMode<E>,
1408 ) -> Result<(), ErrMode<E>> {
1409 Err(err)
1410 }
1411
1412 /// Report whether the [`Stream`] can save off errors for recovery
1413 #[inline(always)]
1414 fn is_recovery_supported() -> bool {
1415 false
1416 }
1417}
1418
1419#[cfg(feature = "unstable-recover")]
1420impl<I, E> Recover<E> for Located<I>
1421where
1422 I: Recover<E>,
1423 I: Stream,
1424{
1425 #[inline(always)]
1426 fn record_err(
1427 &mut self,
1428 _token_start: &Self::Checkpoint,
1429 _err_start: &Self::Checkpoint,
1430 err: ErrMode<E>,
1431 ) -> Result<(), ErrMode<E>> {
1432 Err(err)
1433 }
1434
1435 /// Report whether the [`Stream`] can save off errors for recovery
1436 #[inline(always)]
1437 fn is_recovery_supported() -> bool {
1438 false
1439 }
1440}
1441
1442#[cfg(feature = "unstable-recover")]
1443impl<I, E, R> Recover<E> for Recoverable<I, R>
1444where
1445 I: Stream,
1446 R: FromRecoverableError<Self, E>,
1447 R: crate::lib::std::fmt::Debug,
1448{
1449 fn record_err(
1450 &mut self,
1451 token_start: &Self::Checkpoint,
1452 err_start: &Self::Checkpoint,
1453 err: ErrMode<E>,
1454 ) -> Result<(), ErrMode<E>> {
1455 if self.is_recoverable {
1456 match err {
1457 ErrMode::Incomplete(need) => Err(ErrMode::Incomplete(need)),
1458 ErrMode::Backtrack(err) | ErrMode::Cut(err) => {
1459 self.errors
1460 .push(R::from_recoverable_error(token_start, err_start, self, err));
1461 Ok(())
1462 }
1463 }
1464 } else {
1465 Err(err)
1466 }
1467 }
1468
1469 /// Report whether the [`Stream`] can save off errors for recovery
1470 #[inline(always)]
1471 fn is_recovery_supported() -> bool {
1472 true
1473 }
1474}
1475
1476#[cfg(feature = "unstable-recover")]
1477impl<I, E, S> Recover<E> for Stateful<I, S>
1478where
1479 I: Recover<E>,
1480 I: Stream,
1481 S: Clone + crate::lib::std::fmt::Debug,
1482{
1483 #[inline(always)]
1484 fn record_err(
1485 &mut self,
1486 _token_start: &Self::Checkpoint,
1487 _err_start: &Self::Checkpoint,
1488 err: ErrMode<E>,
1489 ) -> Result<(), ErrMode<E>> {
1490 Err(err)
1491 }
1492
1493 /// Report whether the [`Stream`] can save off errors for recovery
1494 #[inline(always)]
1495 fn is_recovery_supported() -> bool {
1496 false
1497 }
1498}
1499
1500#[cfg(feature = "unstable-recover")]
1501impl<I, E> Recover<E> for Partial<I>
1502where
1503 I: Recover<E>,
1504 I: Stream,
1505{
1506 #[inline(always)]
1507 fn record_err(
1508 &mut self,
1509 _token_start: &Self::Checkpoint,
1510 _err_start: &Self::Checkpoint,
1511 err: ErrMode<E>,
1512 ) -> Result<(), ErrMode<E>> {
1513 Err(err)
1514 }
1515
1516 /// Report whether the [`Stream`] can save off errors for recovery
1517 #[inline(always)]
1518 fn is_recovery_supported() -> bool {
1519 false
1520 }
1521}
1522
1523/// Marks the input as being the complete buffer or a partial buffer for streaming input
1524///
1525/// See [`Partial`] for marking a presumed complete buffer type as a streaming buffer.
1526pub trait StreamIsPartial: Sized {
1527 /// Whether the stream is currently partial or complete
1528 type PartialState;
1529
1530 /// Mark the stream is complete
1531 #[must_use]
1532 fn complete(&mut self) -> Self::PartialState;
1533
1534 /// Restore the stream back to its previous state
1535 fn restore_partial(&mut self, state: Self::PartialState);
1536
1537 /// Report whether the [`Stream`] is can ever be incomplete
1538 fn is_partial_supported() -> bool;
1539
1540 /// Report whether the [`Stream`] is currently incomplete
1541 #[inline(always)]
1542 fn is_partial(&self) -> bool {
1543 Self::is_partial_supported()
1544 }
1545}
1546
1547impl<'a, T> StreamIsPartial for &'a [T] {
1548 type PartialState = ();
1549
1550 fn complete(&mut self) -> Self::PartialState {}
1551
1552 fn restore_partial(&mut self, _state: Self::PartialState) {}
1553
1554 #[inline(always)]
1555 fn is_partial_supported() -> bool {
1556 false
1557 }
1558}
1559
1560impl<'a> StreamIsPartial for &'a str {
1561 type PartialState = ();
1562
1563 fn complete(&mut self) -> Self::PartialState {
1564 // Already complete
1565 }
1566
1567 fn restore_partial(&mut self, _state: Self::PartialState) {}
1568
1569 #[inline(always)]
1570 fn is_partial_supported() -> bool {
1571 false
1572 }
1573}
1574
1575impl<'a> StreamIsPartial for &'a Bytes {
1576 type PartialState = ();
1577
1578 fn complete(&mut self) -> Self::PartialState {
1579 // Already complete
1580 }
1581
1582 fn restore_partial(&mut self, _state: Self::PartialState) {}
1583
1584 #[inline(always)]
1585 fn is_partial_supported() -> bool {
1586 false
1587 }
1588}
1589
1590impl<'a> StreamIsPartial for &'a BStr {
1591 type PartialState = ();
1592
1593 fn complete(&mut self) -> Self::PartialState {
1594 // Already complete
1595 }
1596
1597 fn restore_partial(&mut self, _state: Self::PartialState) {}
1598
1599 #[inline(always)]
1600 fn is_partial_supported() -> bool {
1601 false
1602 }
1603}
1604
1605impl<I> StreamIsPartial for (I, usize)
1606where
1607 I: StreamIsPartial,
1608{
1609 type PartialState = I::PartialState;
1610
1611 fn complete(&mut self) -> Self::PartialState {
1612 self.0.complete()
1613 }
1614
1615 fn restore_partial(&mut self, state: Self::PartialState) {
1616 self.0.restore_partial(state);
1617 }
1618
1619 #[inline(always)]
1620 fn is_partial_supported() -> bool {
1621 I::is_partial_supported()
1622 }
1623
1624 #[inline(always)]
1625 fn is_partial(&self) -> bool {
1626 self.0.is_partial()
1627 }
1628}
1629
1630impl<I> StreamIsPartial for Located<I>
1631where
1632 I: StreamIsPartial,
1633{
1634 type PartialState = I::PartialState;
1635
1636 fn complete(&mut self) -> Self::PartialState {
1637 self.input.complete()
1638 }
1639
1640 fn restore_partial(&mut self, state: Self::PartialState) {
1641 self.input.restore_partial(state);
1642 }
1643
1644 #[inline(always)]
1645 fn is_partial_supported() -> bool {
1646 I::is_partial_supported()
1647 }
1648
1649 #[inline(always)]
1650 fn is_partial(&self) -> bool {
1651 self.input.is_partial()
1652 }
1653}
1654
1655#[cfg(feature = "unstable-recover")]
1656impl<I, E> StreamIsPartial for Recoverable<I, E>
1657where
1658 I: StreamIsPartial,
1659 I: Stream,
1660{
1661 type PartialState = I::PartialState;
1662
1663 fn complete(&mut self) -> Self::PartialState {
1664 self.input.complete()
1665 }
1666
1667 fn restore_partial(&mut self, state: Self::PartialState) {
1668 self.input.restore_partial(state);
1669 }
1670
1671 #[inline(always)]
1672 fn is_partial_supported() -> bool {
1673 I::is_partial_supported()
1674 }
1675
1676 #[inline(always)]
1677 fn is_partial(&self) -> bool {
1678 self.input.is_partial()
1679 }
1680}
1681
1682impl<I, S> StreamIsPartial for Stateful<I, S>
1683where
1684 I: StreamIsPartial,
1685{
1686 type PartialState = I::PartialState;
1687
1688 fn complete(&mut self) -> Self::PartialState {
1689 self.input.complete()
1690 }
1691
1692 fn restore_partial(&mut self, state: Self::PartialState) {
1693 self.input.restore_partial(state);
1694 }
1695
1696 #[inline(always)]
1697 fn is_partial_supported() -> bool {
1698 I::is_partial_supported()
1699 }
1700
1701 #[inline(always)]
1702 fn is_partial(&self) -> bool {
1703 self.input.is_partial()
1704 }
1705}
1706
1707impl<I> StreamIsPartial for Partial<I>
1708where
1709 I: StreamIsPartial,
1710{
1711 type PartialState = bool;
1712
1713 fn complete(&mut self) -> Self::PartialState {
1714 core::mem::replace(&mut self.partial, src:false)
1715 }
1716
1717 fn restore_partial(&mut self, state: Self::PartialState) {
1718 self.partial = state;
1719 }
1720
1721 #[inline(always)]
1722 fn is_partial_supported() -> bool {
1723 true
1724 }
1725
1726 #[inline(always)]
1727 fn is_partial(&self) -> bool {
1728 self.partial
1729 }
1730}
1731
1732/// Useful functions to calculate the offset between slices and show a hexdump of a slice
1733pub trait Offset<Start = Self> {
1734 /// Offset between the first byte of `start` and the first byte of `self`a
1735 ///
1736 /// **Note:** This is an offset, not an index, and may point to the end of input
1737 /// (`start.len()`) when `self` is exhausted.
1738 fn offset_from(&self, start: &Start) -> usize;
1739}
1740
1741impl<'a, T> Offset for &'a [T] {
1742 #[inline]
1743 fn offset_from(&self, start: &Self) -> usize {
1744 let fst: *const T = (*start).as_ptr();
1745 let snd: *const T = (*self).as_ptr();
1746
1747 debug_assert!(
1748 fst <= snd,
1749 "`Offset::offset_from({snd:?}, {fst:?})` only accepts slices of `self`"
1750 );
1751 (snd as usize - fst as usize) / crate::lib::std::mem::size_of::<T>()
1752 }
1753}
1754
1755impl<'a, T> Offset<<&'a [T] as Stream>::Checkpoint> for &'a [T]
1756where
1757 T: Clone + crate::lib::std::fmt::Debug,
1758{
1759 #[inline(always)]
1760 fn offset_from(&self, other: &<&'a [T] as Stream>::Checkpoint) -> usize {
1761 self.checkpoint().offset_from(start:other)
1762 }
1763}
1764
1765impl<'a> Offset for &'a str {
1766 #[inline(always)]
1767 fn offset_from(&self, start: &Self) -> usize {
1768 self.as_bytes().offset_from(&start.as_bytes())
1769 }
1770}
1771
1772impl<'a> Offset<<&'a str as Stream>::Checkpoint> for &'a str {
1773 #[inline(always)]
1774 fn offset_from(&self, other: &<&'a str as Stream>::Checkpoint) -> usize {
1775 self.checkpoint().offset_from(start:other)
1776 }
1777}
1778
1779impl<'a> Offset for &'a Bytes {
1780 #[inline(always)]
1781 fn offset_from(&self, start: &Self) -> usize {
1782 self.as_bytes().offset_from(&start.as_bytes())
1783 }
1784}
1785
1786impl<'a> Offset<<&'a Bytes as Stream>::Checkpoint> for &'a Bytes {
1787 #[inline(always)]
1788 fn offset_from(&self, other: &<&'a Bytes as Stream>::Checkpoint) -> usize {
1789 self.checkpoint().offset_from(start:other)
1790 }
1791}
1792
1793impl<'a> Offset for &'a BStr {
1794 #[inline(always)]
1795 fn offset_from(&self, start: &Self) -> usize {
1796 self.as_bytes().offset_from(&start.as_bytes())
1797 }
1798}
1799
1800impl<'a> Offset<<&'a BStr as Stream>::Checkpoint> for &'a BStr {
1801 #[inline(always)]
1802 fn offset_from(&self, other: &<&'a BStr as Stream>::Checkpoint) -> usize {
1803 self.checkpoint().offset_from(start:other)
1804 }
1805}
1806
1807impl<I> Offset for (I, usize)
1808where
1809 I: Offset,
1810{
1811 #[inline(always)]
1812 fn offset_from(&self, start: &Self) -> usize {
1813 self.0.offset_from(&start.0) * 8 + self.1 - start.1
1814 }
1815}
1816
1817impl<I> Offset<<(I, usize) as Stream>::Checkpoint> for (I, usize)
1818where
1819 I: Stream<Token = u8> + Clone,
1820{
1821 #[inline(always)]
1822 fn offset_from(&self, other: &<(I, usize) as Stream>::Checkpoint) -> usize {
1823 self.checkpoint().offset_from(start:other)
1824 }
1825}
1826
1827impl<I> Offset for Located<I>
1828where
1829 I: Stream,
1830{
1831 #[inline(always)]
1832 fn offset_from(&self, other: &Self) -> usize {
1833 self.offset_from(&other.checkpoint())
1834 }
1835}
1836
1837impl<I> Offset<<Located<I> as Stream>::Checkpoint> for Located<I>
1838where
1839 I: Stream,
1840{
1841 #[inline(always)]
1842 fn offset_from(&self, other: &<Located<I> as Stream>::Checkpoint) -> usize {
1843 self.checkpoint().offset_from(start:other)
1844 }
1845}
1846
1847#[cfg(feature = "unstable-recover")]
1848impl<I, E> Offset for Recoverable<I, E>
1849where
1850 I: Stream,
1851 E: crate::lib::std::fmt::Debug,
1852{
1853 #[inline(always)]
1854 fn offset_from(&self, other: &Self) -> usize {
1855 self.offset_from(&other.checkpoint())
1856 }
1857}
1858
1859#[cfg(feature = "unstable-recover")]
1860impl<I, E> Offset<<Recoverable<I, E> as Stream>::Checkpoint> for Recoverable<I, E>
1861where
1862 I: Stream,
1863 E: crate::lib::std::fmt::Debug,
1864{
1865 #[inline(always)]
1866 fn offset_from(&self, other: &<Recoverable<I, E> as Stream>::Checkpoint) -> usize {
1867 self.checkpoint().offset_from(other)
1868 }
1869}
1870
1871impl<I, S> Offset for Stateful<I, S>
1872where
1873 I: Stream,
1874 S: Clone + crate::lib::std::fmt::Debug,
1875{
1876 #[inline(always)]
1877 fn offset_from(&self, start: &Self) -> usize {
1878 self.offset_from(&start.checkpoint())
1879 }
1880}
1881
1882impl<I, S> Offset<<Stateful<I, S> as Stream>::Checkpoint> for Stateful<I, S>
1883where
1884 I: Stream,
1885 S: crate::lib::std::fmt::Debug,
1886{
1887 #[inline(always)]
1888 fn offset_from(&self, other: &<Stateful<I, S> as Stream>::Checkpoint) -> usize {
1889 self.checkpoint().offset_from(start:other)
1890 }
1891}
1892
1893impl<I> Offset for Partial<I>
1894where
1895 I: Stream,
1896{
1897 #[inline(always)]
1898 fn offset_from(&self, start: &Self) -> usize {
1899 self.offset_from(&start.checkpoint())
1900 }
1901}
1902
1903impl<I> Offset<<Partial<I> as Stream>::Checkpoint> for Partial<I>
1904where
1905 I: Stream,
1906{
1907 #[inline(always)]
1908 fn offset_from(&self, other: &<Partial<I> as Stream>::Checkpoint) -> usize {
1909 self.checkpoint().offset_from(start:other)
1910 }
1911}
1912
1913impl<I> Offset for Checkpoint<I>
1914where
1915 I: Offset,
1916{
1917 #[inline(always)]
1918 fn offset_from(&self, start: &Self) -> usize {
1919 self.0.offset_from(&start.0)
1920 }
1921}
1922
1923/// Helper trait for types that can be viewed as a byte slice
1924pub trait AsBytes {
1925 /// Casts the input type to a byte slice
1926 fn as_bytes(&self) -> &[u8];
1927}
1928
1929impl<'a> AsBytes for &'a [u8] {
1930 #[inline(always)]
1931 fn as_bytes(&self) -> &[u8] {
1932 self
1933 }
1934}
1935
1936impl<'a> AsBytes for &'a Bytes {
1937 #[inline(always)]
1938 fn as_bytes(&self) -> &[u8] {
1939 (*self).as_bytes()
1940 }
1941}
1942
1943impl<I> AsBytes for Located<I>
1944where
1945 I: AsBytes,
1946{
1947 #[inline(always)]
1948 fn as_bytes(&self) -> &[u8] {
1949 self.input.as_bytes()
1950 }
1951}
1952
1953#[cfg(feature = "unstable-recover")]
1954impl<I, E> AsBytes for Recoverable<I, E>
1955where
1956 I: Stream,
1957 I: AsBytes,
1958{
1959 #[inline(always)]
1960 fn as_bytes(&self) -> &[u8] {
1961 self.input.as_bytes()
1962 }
1963}
1964
1965impl<I, S> AsBytes for Stateful<I, S>
1966where
1967 I: AsBytes,
1968{
1969 #[inline(always)]
1970 fn as_bytes(&self) -> &[u8] {
1971 self.input.as_bytes()
1972 }
1973}
1974
1975impl<I> AsBytes for Partial<I>
1976where
1977 I: AsBytes,
1978{
1979 #[inline(always)]
1980 fn as_bytes(&self) -> &[u8] {
1981 self.input.as_bytes()
1982 }
1983}
1984
1985/// Helper trait for types that can be viewed as a byte slice
1986pub trait AsBStr {
1987 /// Casts the input type to a byte slice
1988 fn as_bstr(&self) -> &[u8];
1989}
1990
1991impl<'a> AsBStr for &'a [u8] {
1992 #[inline(always)]
1993 fn as_bstr(&self) -> &[u8] {
1994 self
1995 }
1996}
1997
1998impl<'a> AsBStr for &'a BStr {
1999 #[inline(always)]
2000 fn as_bstr(&self) -> &[u8] {
2001 (*self).as_bytes()
2002 }
2003}
2004
2005impl<'a> AsBStr for &'a str {
2006 #[inline(always)]
2007 fn as_bstr(&self) -> &[u8] {
2008 (*self).as_bytes()
2009 }
2010}
2011
2012impl<I> AsBStr for Located<I>
2013where
2014 I: AsBStr,
2015{
2016 #[inline(always)]
2017 fn as_bstr(&self) -> &[u8] {
2018 self.input.as_bstr()
2019 }
2020}
2021
2022#[cfg(feature = "unstable-recover")]
2023impl<I, E> AsBStr for Recoverable<I, E>
2024where
2025 I: Stream,
2026 I: AsBStr,
2027{
2028 #[inline(always)]
2029 fn as_bstr(&self) -> &[u8] {
2030 self.input.as_bstr()
2031 }
2032}
2033
2034impl<I, S> AsBStr for Stateful<I, S>
2035where
2036 I: AsBStr,
2037{
2038 #[inline(always)]
2039 fn as_bstr(&self) -> &[u8] {
2040 self.input.as_bstr()
2041 }
2042}
2043
2044impl<I> AsBStr for Partial<I>
2045where
2046 I: AsBStr,
2047{
2048 #[inline(always)]
2049 fn as_bstr(&self) -> &[u8] {
2050 self.input.as_bstr()
2051 }
2052}
2053
2054/// Result of [`Compare::compare`]
2055#[derive(Debug, Eq, PartialEq)]
2056pub enum CompareResult {
2057 /// Comparison was successful
2058 Ok,
2059 /// We need more data to be sure
2060 Incomplete,
2061 /// Comparison failed
2062 Error,
2063}
2064
2065/// Abstracts comparison operations
2066pub trait Compare<T> {
2067 /// Compares self to another value for equality
2068 fn compare(&self, t: T) -> CompareResult;
2069 /// Compares self to another value for equality
2070 /// independently of the case.
2071 ///
2072 /// Warning: for `&str`, the comparison is done
2073 /// by lowercasing both strings and comparing
2074 /// the result. This is a temporary solution until
2075 /// a better one appears
2076 #[deprecated(since = "0.5.20", note = "Replaced with `compare(ascii::Caseless(_))`")]
2077 fn compare_no_case(&self, t: T) -> CompareResult;
2078}
2079
2080impl<'a, 'b> Compare<&'b [u8]> for &'a [u8] {
2081 #[inline]
2082 fn compare(&self, t: &'b [u8]) -> CompareResult {
2083 if t.iter().zip(*self).any(|(a: &u8, b: &u8)| a != b) {
2084 CompareResult::Error
2085 } else if self.len() < t.slice_len() {
2086 CompareResult::Incomplete
2087 } else {
2088 CompareResult::Ok
2089 }
2090 }
2091
2092 #[inline(always)]
2093 #[allow(deprecated)]
2094 fn compare_no_case(&self, t: &'b [u8]) -> CompareResult {
2095 self.compare(AsciiCaseless(t))
2096 }
2097}
2098
2099impl<'a, 'b> Compare<AsciiCaseless<&'b [u8]>> for &'a [u8] {
2100 #[inline]
2101 fn compare(&self, t: AsciiCaseless<&'b [u8]>) -> CompareResult {
2102 if timpl Iterator.0
2103 .iter()
2104 .zip(*self)
2105 .any(|(a: &u8, b: &u8)| !a.eq_ignore_ascii_case(b))
2106 {
2107 CompareResult::Error
2108 } else if self.len() < t.slice_len() {
2109 CompareResult::Incomplete
2110 } else {
2111 CompareResult::Ok
2112 }
2113 }
2114
2115 #[inline(always)]
2116 #[allow(deprecated)]
2117 fn compare_no_case(&self, t: AsciiCaseless<&'b [u8]>) -> CompareResult {
2118 self.compare(t)
2119 }
2120}
2121
2122impl<'a, const LEN: usize> Compare<[u8; LEN]> for &'a [u8] {
2123 #[inline(always)]
2124 fn compare(&self, t: [u8; LEN]) -> CompareResult {
2125 self.compare(&t[..])
2126 }
2127
2128 #[inline(always)]
2129 #[allow(deprecated)]
2130 fn compare_no_case(&self, t: [u8; LEN]) -> CompareResult {
2131 self.compare_no_case(&t[..])
2132 }
2133}
2134
2135impl<'a, const LEN: usize> Compare<AsciiCaseless<[u8; LEN]>> for &'a [u8] {
2136 #[inline(always)]
2137 fn compare(&self, t: AsciiCaseless<[u8; LEN]>) -> CompareResult {
2138 self.compare(AsciiCaseless(&t.0[..]))
2139 }
2140
2141 #[inline(always)]
2142 #[allow(deprecated)]
2143 fn compare_no_case(&self, t: AsciiCaseless<[u8; LEN]>) -> CompareResult {
2144 self.compare_no_case(AsciiCaseless(&t.0[..]))
2145 }
2146}
2147
2148impl<'a, 'b, const LEN: usize> Compare<&'b [u8; LEN]> for &'a [u8] {
2149 #[inline(always)]
2150 fn compare(&self, t: &'b [u8; LEN]) -> CompareResult {
2151 self.compare(&t[..])
2152 }
2153
2154 #[inline(always)]
2155 #[allow(deprecated)]
2156 fn compare_no_case(&self, t: &'b [u8; LEN]) -> CompareResult {
2157 self.compare_no_case(&t[..])
2158 }
2159}
2160
2161impl<'a, 'b, const LEN: usize> Compare<AsciiCaseless<&'b [u8; LEN]>> for &'a [u8] {
2162 #[inline(always)]
2163 fn compare(&self, t: AsciiCaseless<&'b [u8; LEN]>) -> CompareResult {
2164 self.compare(AsciiCaseless(&t.0[..]))
2165 }
2166
2167 #[inline(always)]
2168 #[allow(deprecated)]
2169 fn compare_no_case(&self, t: AsciiCaseless<&'b [u8; LEN]>) -> CompareResult {
2170 self.compare_no_case(AsciiCaseless(&t.0[..]))
2171 }
2172}
2173
2174impl<'a, 'b> Compare<&'b str> for &'a [u8] {
2175 #[inline(always)]
2176 fn compare(&self, t: &'b str) -> CompareResult {
2177 self.compare(t.as_bytes())
2178 }
2179 #[inline(always)]
2180 #[allow(deprecated)]
2181 fn compare_no_case(&self, t: &'b str) -> CompareResult {
2182 self.compare_no_case(t.as_bytes())
2183 }
2184}
2185
2186impl<'a, 'b> Compare<AsciiCaseless<&'b str>> for &'a [u8] {
2187 #[inline(always)]
2188 fn compare(&self, t: AsciiCaseless<&'b str>) -> CompareResult {
2189 self.compare(AsciiCaseless(t.0.as_bytes()))
2190 }
2191 #[inline(always)]
2192 #[allow(deprecated)]
2193 fn compare_no_case(&self, t: AsciiCaseless<&'b str>) -> CompareResult {
2194 self.compare_no_case(AsciiCaseless(t.0.as_bytes()))
2195 }
2196}
2197
2198impl<'a> Compare<u8> for &'a [u8] {
2199 #[inline]
2200 fn compare(&self, t: u8) -> CompareResult {
2201 match self.first().copied() {
2202 Some(c: u8) if t == c => CompareResult::Ok,
2203 Some(_) => CompareResult::Error,
2204 None => CompareResult::Incomplete,
2205 }
2206 }
2207 #[inline(always)]
2208 #[allow(deprecated)]
2209 fn compare_no_case(&self, t: u8) -> CompareResult {
2210 self.compare(AsciiCaseless(t))
2211 }
2212}
2213
2214impl<'a> Compare<AsciiCaseless<u8>> for &'a [u8] {
2215 #[inline]
2216 fn compare(&self, t: AsciiCaseless<u8>) -> CompareResult {
2217 match self.first() {
2218 Some(c: &u8) if t.0.eq_ignore_ascii_case(c) => CompareResult::Ok,
2219 Some(_) => CompareResult::Error,
2220 None => CompareResult::Incomplete,
2221 }
2222 }
2223 #[inline(always)]
2224 #[allow(deprecated)]
2225 fn compare_no_case(&self, t: AsciiCaseless<u8>) -> CompareResult {
2226 self.compare(t)
2227 }
2228}
2229
2230impl<'a> Compare<char> for &'a [u8] {
2231 #[inline(always)]
2232 fn compare(&self, t: char) -> CompareResult {
2233 self.compare(t.encode_utf8(&mut [0; 4]).as_bytes())
2234 }
2235
2236 #[inline(always)]
2237 #[allow(deprecated)]
2238 fn compare_no_case(&self, t: char) -> CompareResult {
2239 self.compare_no_case(t.encode_utf8(&mut [0; 4]).as_bytes())
2240 }
2241}
2242
2243impl<'a> Compare<AsciiCaseless<char>> for &'a [u8] {
2244 #[inline(always)]
2245 fn compare(&self, t: AsciiCaseless<char>) -> CompareResult {
2246 self.compare(AsciiCaseless(t.0.encode_utf8(&mut [0; 4]).as_bytes()))
2247 }
2248
2249 #[inline(always)]
2250 #[allow(deprecated)]
2251 fn compare_no_case(&self, t: AsciiCaseless<char>) -> CompareResult {
2252 self.compare_no_case(AsciiCaseless(t.0.encode_utf8(&mut [0; 4]).as_bytes()))
2253 }
2254}
2255
2256impl<'a, 'b> Compare<&'b str> for &'a str {
2257 #[inline(always)]
2258 fn compare(&self, t: &'b str) -> CompareResult {
2259 self.as_bytes().compare(t.as_bytes())
2260 }
2261
2262 #[inline]
2263 #[allow(deprecated)]
2264 fn compare_no_case(&self, t: &'b str) -> CompareResult {
2265 self.compare(AsciiCaseless(t))
2266 }
2267}
2268
2269impl<'a, 'b> Compare<AsciiCaseless<&'b str>> for &'a str {
2270 #[inline(always)]
2271 fn compare(&self, t: AsciiCaseless<&'b str>) -> CompareResult {
2272 self.as_bytes().compare(t.as_bytes())
2273 }
2274
2275 #[inline(always)]
2276 #[allow(deprecated)]
2277 fn compare_no_case(&self, t: AsciiCaseless<&'b str>) -> CompareResult {
2278 self.compare(t)
2279 }
2280}
2281
2282impl<'a> Compare<u8> for &'a str {
2283 #[inline(always)]
2284 fn compare(&self, t: u8) -> CompareResult {
2285 self.as_bytes().compare(t)
2286 }
2287 #[inline(always)]
2288 #[allow(deprecated)]
2289 fn compare_no_case(&self, t: u8) -> CompareResult {
2290 self.compare(AsciiCaseless(t))
2291 }
2292}
2293
2294impl<'a> Compare<AsciiCaseless<u8>> for &'a str {
2295 #[inline(always)]
2296 fn compare(&self, t: AsciiCaseless<u8>) -> CompareResult {
2297 self.as_bytes().compare(t)
2298 }
2299 #[inline(always)]
2300 #[allow(deprecated)]
2301 fn compare_no_case(&self, t: AsciiCaseless<u8>) -> CompareResult {
2302 self.compare(t)
2303 }
2304}
2305
2306impl<'a> Compare<char> for &'a str {
2307 #[inline(always)]
2308 fn compare(&self, t: char) -> CompareResult {
2309 self.as_bytes().compare(t)
2310 }
2311
2312 #[inline(always)]
2313 #[allow(deprecated)]
2314 fn compare_no_case(&self, t: char) -> CompareResult {
2315 self.compare_no_case(t.encode_utf8(&mut [0; 4]).as_bytes())
2316 }
2317}
2318
2319impl<'a> Compare<AsciiCaseless<char>> for &'a str {
2320 #[inline(always)]
2321 fn compare(&self, t: AsciiCaseless<char>) -> CompareResult {
2322 self.as_bytes().compare(t)
2323 }
2324
2325 #[inline(always)]
2326 #[allow(deprecated)]
2327 fn compare_no_case(&self, t: AsciiCaseless<char>) -> CompareResult {
2328 self.compare_no_case(AsciiCaseless(t.0.encode_utf8(&mut [0; 4]).as_bytes()))
2329 }
2330}
2331
2332impl<'a, 'b> Compare<&'b [u8]> for &'a str {
2333 #[inline(always)]
2334 fn compare(&self, t: &'b [u8]) -> CompareResult {
2335 self.as_bytes().compare(t)
2336 }
2337 #[inline(always)]
2338 #[allow(deprecated)]
2339 fn compare_no_case(&self, t: &'b [u8]) -> CompareResult {
2340 AsBStr::as_bstr(self).compare_no_case(t)
2341 }
2342}
2343
2344impl<'a, 'b> Compare<AsciiCaseless<&'b [u8]>> for &'a str {
2345 #[inline(always)]
2346 fn compare(&self, t: AsciiCaseless<&'b [u8]>) -> CompareResult {
2347 self.as_bytes().compare(t)
2348 }
2349 #[inline(always)]
2350 #[allow(deprecated)]
2351 fn compare_no_case(&self, t: AsciiCaseless<&'b [u8]>) -> CompareResult {
2352 AsBStr::as_bstr(self).compare_no_case(t)
2353 }
2354}
2355
2356impl<'a, T> Compare<T> for &'a Bytes
2357where
2358 &'a [u8]: Compare<T>,
2359{
2360 #[inline(always)]
2361 fn compare(&self, t: T) -> CompareResult {
2362 let bytes: &[u8] = (*self).as_bytes();
2363 bytes.compare(t)
2364 }
2365
2366 #[inline(always)]
2367 #[allow(deprecated)]
2368 fn compare_no_case(&self, t: T) -> CompareResult {
2369 let bytes: &[u8] = (*self).as_bytes();
2370 bytes.compare_no_case(t)
2371 }
2372}
2373
2374impl<'a, T> Compare<T> for &'a BStr
2375where
2376 &'a [u8]: Compare<T>,
2377{
2378 #[inline(always)]
2379 fn compare(&self, t: T) -> CompareResult {
2380 let bytes: &[u8] = (*self).as_bytes();
2381 bytes.compare(t)
2382 }
2383
2384 #[inline(always)]
2385 #[allow(deprecated)]
2386 fn compare_no_case(&self, t: T) -> CompareResult {
2387 let bytes: &[u8] = (*self).as_bytes();
2388 bytes.compare_no_case(t)
2389 }
2390}
2391
2392impl<I, U> Compare<U> for Located<I>
2393where
2394 I: Compare<U>,
2395{
2396 #[inline(always)]
2397 fn compare(&self, other: U) -> CompareResult {
2398 self.input.compare(other)
2399 }
2400
2401 #[inline(always)]
2402 #[allow(deprecated)]
2403 fn compare_no_case(&self, other: U) -> CompareResult {
2404 self.input.compare_no_case(other)
2405 }
2406}
2407
2408#[cfg(feature = "unstable-recover")]
2409impl<I, E, U> Compare<U> for Recoverable<I, E>
2410where
2411 I: Stream,
2412 I: Compare<U>,
2413{
2414 #[inline(always)]
2415 fn compare(&self, other: U) -> CompareResult {
2416 self.input.compare(other)
2417 }
2418
2419 #[inline(always)]
2420 #[allow(deprecated)]
2421 fn compare_no_case(&self, other: U) -> CompareResult {
2422 self.input.compare_no_case(other)
2423 }
2424}
2425
2426impl<I, S, U> Compare<U> for Stateful<I, S>
2427where
2428 I: Compare<U>,
2429{
2430 #[inline(always)]
2431 fn compare(&self, other: U) -> CompareResult {
2432 self.input.compare(other)
2433 }
2434
2435 #[inline(always)]
2436 #[allow(deprecated)]
2437 fn compare_no_case(&self, other: U) -> CompareResult {
2438 self.input.compare_no_case(other)
2439 }
2440}
2441
2442impl<I, T> Compare<T> for Partial<I>
2443where
2444 I: Compare<T>,
2445{
2446 #[inline(always)]
2447 fn compare(&self, t: T) -> CompareResult {
2448 self.input.compare(t)
2449 }
2450
2451 #[inline(always)]
2452 #[allow(deprecated)]
2453 fn compare_no_case(&self, t: T) -> CompareResult {
2454 self.input.compare_no_case(t)
2455 }
2456}
2457
2458/// Look for a slice in self
2459pub trait FindSlice<T> {
2460 /// Returns the offset of the slice if it is found
2461 fn find_slice(&self, substr: T) -> Option<usize>;
2462}
2463
2464impl<'i, 's> FindSlice<&'s [u8]> for &'i [u8] {
2465 #[inline(always)]
2466 fn find_slice(&self, substr: &'s [u8]) -> Option<usize> {
2467 memmem(self, tag:substr)
2468 }
2469}
2470
2471impl<'i, 's> FindSlice<(&'s [u8],)> for &'i [u8] {
2472 #[inline(always)]
2473 fn find_slice(&self, substr: (&'s [u8],)) -> Option<usize> {
2474 memmem(self, tag:substr.0)
2475 }
2476}
2477
2478impl<'i, 's> FindSlice<(&'s [u8], &'s [u8])> for &'i [u8] {
2479 #[inline(always)]
2480 fn find_slice(&self, substr: (&'s [u8], &'s [u8])) -> Option<usize> {
2481 memmem2(self, tag:substr)
2482 }
2483}
2484
2485impl<'i, 's> FindSlice<(&'s [u8], &'s [u8], &'s [u8])> for &'i [u8] {
2486 #[inline(always)]
2487 fn find_slice(&self, substr: (&'s [u8], &'s [u8], &'s [u8])) -> Option<usize> {
2488 memmem3(self, tag:substr)
2489 }
2490}
2491
2492impl<'i> FindSlice<char> for &'i [u8] {
2493 #[inline(always)]
2494 fn find_slice(&self, substr: char) -> Option<usize> {
2495 let mut b: [u8; 4] = [0; 4];
2496 let substr: &mut str = substr.encode_utf8(&mut b);
2497 self.find_slice(&*substr)
2498 }
2499}
2500
2501impl<'i> FindSlice<(char,)> for &'i [u8] {
2502 #[inline(always)]
2503 fn find_slice(&self, substr: (char,)) -> Option<usize> {
2504 let mut b: [u8; 4] = [0; 4];
2505 let substr0: &mut str = substr.0.encode_utf8(&mut b);
2506 self.find_slice((&*substr0,))
2507 }
2508}
2509
2510impl<'i> FindSlice<(char, char)> for &'i [u8] {
2511 #[inline(always)]
2512 fn find_slice(&self, substr: (char, char)) -> Option<usize> {
2513 let mut b: [u8; 4] = [0; 4];
2514 let substr0: &mut str = substr.0.encode_utf8(&mut b);
2515 let mut b: [u8; 4] = [0; 4];
2516 let substr1: &mut str = substr.1.encode_utf8(&mut b);
2517 self.find_slice((&*substr0, &*substr1))
2518 }
2519}
2520
2521impl<'i> FindSlice<(char, char, char)> for &'i [u8] {
2522 #[inline(always)]
2523 fn find_slice(&self, substr: (char, char, char)) -> Option<usize> {
2524 let mut b: [u8; 4] = [0; 4];
2525 let substr0: &mut str = substr.0.encode_utf8(&mut b);
2526 let mut b: [u8; 4] = [0; 4];
2527 let substr1: &mut str = substr.1.encode_utf8(&mut b);
2528 let mut b: [u8; 4] = [0; 4];
2529 let substr2: &mut str = substr.2.encode_utf8(&mut b);
2530 self.find_slice((&*substr0, &*substr1, &*substr2))
2531 }
2532}
2533
2534impl<'i> FindSlice<u8> for &'i [u8] {
2535 #[inline(always)]
2536 fn find_slice(&self, substr: u8) -> Option<usize> {
2537 memchr(token:substr, self)
2538 }
2539}
2540
2541impl<'i> FindSlice<(u8,)> for &'i [u8] {
2542 #[inline(always)]
2543 fn find_slice(&self, substr: (u8,)) -> Option<usize> {
2544 memchr(token:substr.0, self)
2545 }
2546}
2547
2548impl<'i> FindSlice<(u8, u8)> for &'i [u8] {
2549 #[inline(always)]
2550 fn find_slice(&self, substr: (u8, u8)) -> Option<usize> {
2551 memchr2(token:substr, self)
2552 }
2553}
2554
2555impl<'i> FindSlice<(u8, u8, u8)> for &'i [u8] {
2556 #[inline(always)]
2557 fn find_slice(&self, substr: (u8, u8, u8)) -> Option<usize> {
2558 memchr3(token:substr, self)
2559 }
2560}
2561
2562impl<'i, 's> FindSlice<&'s str> for &'i [u8] {
2563 #[inline(always)]
2564 fn find_slice(&self, substr: &'s str) -> Option<usize> {
2565 self.find_slice(substr:substr.as_bytes())
2566 }
2567}
2568
2569impl<'i, 's> FindSlice<(&'s str,)> for &'i [u8] {
2570 #[inline(always)]
2571 fn find_slice(&self, substr: (&'s str,)) -> Option<usize> {
2572 memmem(self, tag:substr.0.as_bytes())
2573 }
2574}
2575
2576impl<'i, 's> FindSlice<(&'s str, &'s str)> for &'i [u8] {
2577 #[inline(always)]
2578 fn find_slice(&self, substr: (&'s str, &'s str)) -> Option<usize> {
2579 memmem2(self, (substr.0.as_bytes(), substr.1.as_bytes()))
2580 }
2581}
2582
2583impl<'i, 's> FindSlice<(&'s str, &'s str, &'s str)> for &'i [u8] {
2584 #[inline(always)]
2585 fn find_slice(&self, substr: (&'s str, &'s str, &'s str)) -> Option<usize> {
2586 memmem3(
2587 self,
2588 (
2589 substr.0.as_bytes(),
2590 substr.1.as_bytes(),
2591 substr.2.as_bytes(),
2592 ),
2593 )
2594 }
2595}
2596
2597impl<'i, 's> FindSlice<&'s str> for &'i str {
2598 #[inline(always)]
2599 fn find_slice(&self, substr: &'s str) -> Option<usize> {
2600 self.as_bytes().find_slice(substr)
2601 }
2602}
2603
2604impl<'i, 's> FindSlice<(&'s str,)> for &'i str {
2605 #[inline(always)]
2606 fn find_slice(&self, substr: (&'s str,)) -> Option<usize> {
2607 self.as_bytes().find_slice(substr)
2608 }
2609}
2610
2611impl<'i, 's> FindSlice<(&'s str, &'s str)> for &'i str {
2612 #[inline(always)]
2613 fn find_slice(&self, substr: (&'s str, &'s str)) -> Option<usize> {
2614 self.as_bytes().find_slice(substr)
2615 }
2616}
2617
2618impl<'i, 's> FindSlice<(&'s str, &'s str, &'s str)> for &'i str {
2619 #[inline(always)]
2620 fn find_slice(&self, substr: (&'s str, &'s str, &'s str)) -> Option<usize> {
2621 self.as_bytes().find_slice(substr)
2622 }
2623}
2624
2625impl<'i> FindSlice<char> for &'i str {
2626 #[inline(always)]
2627 fn find_slice(&self, substr: char) -> Option<usize> {
2628 self.as_bytes().find_slice(substr)
2629 }
2630}
2631
2632impl<'i> FindSlice<(char,)> for &'i str {
2633 #[inline(always)]
2634 fn find_slice(&self, substr: (char,)) -> Option<usize> {
2635 self.as_bytes().find_slice(substr)
2636 }
2637}
2638
2639impl<'i> FindSlice<(char, char)> for &'i str {
2640 #[inline(always)]
2641 fn find_slice(&self, substr: (char, char)) -> Option<usize> {
2642 self.as_bytes().find_slice(substr)
2643 }
2644}
2645
2646impl<'i> FindSlice<(char, char, char)> for &'i str {
2647 #[inline(always)]
2648 fn find_slice(&self, substr: (char, char, char)) -> Option<usize> {
2649 self.as_bytes().find_slice(substr)
2650 }
2651}
2652
2653impl<'i> FindSlice<u8> for &'i str {
2654 #[inline(always)]
2655 fn find_slice(&self, substr: u8) -> Option<usize> {
2656 self.as_bytes().find_slice(substr)
2657 }
2658}
2659
2660impl<'i> FindSlice<(u8,)> for &'i str {
2661 #[inline(always)]
2662 fn find_slice(&self, substr: (u8,)) -> Option<usize> {
2663 self.as_bytes().find_slice(substr)
2664 }
2665}
2666
2667impl<'i> FindSlice<(u8, u8)> for &'i str {
2668 #[inline(always)]
2669 fn find_slice(&self, substr: (u8, u8)) -> Option<usize> {
2670 self.as_bytes().find_slice(substr)
2671 }
2672}
2673
2674impl<'i> FindSlice<(u8, u8, u8)> for &'i str {
2675 #[inline(always)]
2676 fn find_slice(&self, substr: (u8, u8, u8)) -> Option<usize> {
2677 self.as_bytes().find_slice(substr)
2678 }
2679}
2680
2681impl<'i, S> FindSlice<S> for &'i Bytes
2682where
2683 &'i [u8]: FindSlice<S>,
2684{
2685 #[inline(always)]
2686 fn find_slice(&self, substr: S) -> Option<usize> {
2687 let bytes: &[u8] = (*self).as_bytes();
2688 let offset: Option = bytes.find_slice(substr);
2689 offset
2690 }
2691}
2692
2693impl<'i, S> FindSlice<S> for &'i BStr
2694where
2695 &'i [u8]: FindSlice<S>,
2696{
2697 #[inline(always)]
2698 fn find_slice(&self, substr: S) -> Option<usize> {
2699 let bytes: &[u8] = (*self).as_bytes();
2700 let offset: Option = bytes.find_slice(substr);
2701 offset
2702 }
2703}
2704
2705impl<I, T> FindSlice<T> for Located<I>
2706where
2707 I: FindSlice<T>,
2708{
2709 #[inline(always)]
2710 fn find_slice(&self, substr: T) -> Option<usize> {
2711 self.input.find_slice(substr)
2712 }
2713}
2714
2715#[cfg(feature = "unstable-recover")]
2716impl<I, E, T> FindSlice<T> for Recoverable<I, E>
2717where
2718 I: Stream,
2719 I: FindSlice<T>,
2720{
2721 #[inline(always)]
2722 fn find_slice(&self, substr: T) -> Option<usize> {
2723 self.input.find_slice(substr)
2724 }
2725}
2726
2727impl<I, S, T> FindSlice<T> for Stateful<I, S>
2728where
2729 I: FindSlice<T>,
2730{
2731 #[inline(always)]
2732 fn find_slice(&self, substr: T) -> Option<usize> {
2733 self.input.find_slice(substr)
2734 }
2735}
2736
2737impl<I, T> FindSlice<T> for Partial<I>
2738where
2739 I: FindSlice<T>,
2740{
2741 #[inline(always)]
2742 fn find_slice(&self, substr: T) -> Option<usize> {
2743 self.input.find_slice(substr)
2744 }
2745}
2746
2747/// Used to integrate `str`'s `parse()` method
2748pub trait ParseSlice<R> {
2749 /// Succeeds if `parse()` succeededThe
2750 ///
2751 /// The byte slice implementation will first convert it to a `&str`, then apply the `parse()`
2752 /// function
2753 fn parse_slice(&self) -> Option<R>;
2754}
2755
2756impl<'a, R: FromStr> ParseSlice<R> for &'a [u8] {
2757 #[inline(always)]
2758 fn parse_slice(&self) -> Option<R> {
2759 from_utf8(self).ok().and_then(|s: &str| s.parse().ok())
2760 }
2761}
2762
2763impl<'a, R: FromStr> ParseSlice<R> for &'a str {
2764 #[inline(always)]
2765 fn parse_slice(&self) -> Option<R> {
2766 self.parse().ok()
2767 }
2768}
2769
2770/// Convert a `Stream` into an appropriate `Output` type
2771pub trait UpdateSlice: Stream {
2772 /// Convert an `Output` type to be used as `Stream`
2773 fn update_slice(self, inner: Self::Slice) -> Self;
2774}
2775
2776impl<'a, T> UpdateSlice for &'a [T]
2777where
2778 T: Clone + crate::lib::std::fmt::Debug,
2779{
2780 #[inline(always)]
2781 fn update_slice(self, inner: Self::Slice) -> Self {
2782 inner
2783 }
2784}
2785
2786impl<'a> UpdateSlice for &'a str {
2787 #[inline(always)]
2788 fn update_slice(self, inner: Self::Slice) -> Self {
2789 inner
2790 }
2791}
2792
2793impl<'a> UpdateSlice for &'a Bytes {
2794 #[inline(always)]
2795 fn update_slice(self, inner: Self::Slice) -> Self {
2796 Bytes::new(bytes:inner)
2797 }
2798}
2799
2800impl<'a> UpdateSlice for &'a BStr {
2801 #[inline(always)]
2802 fn update_slice(self, inner: Self::Slice) -> Self {
2803 BStr::new(bytes:inner)
2804 }
2805}
2806
2807impl<I> UpdateSlice for Located<I>
2808where
2809 I: UpdateSlice,
2810{
2811 #[inline(always)]
2812 fn update_slice(mut self, inner: Self::Slice) -> Self {
2813 self.input = I::update_slice(self.input, inner);
2814 self
2815 }
2816}
2817
2818#[cfg(feature = "unstable-recover")]
2819impl<I, E> UpdateSlice for Recoverable<I, E>
2820where
2821 I: Stream,
2822 I: UpdateSlice,
2823 E: crate::lib::std::fmt::Debug,
2824{
2825 #[inline(always)]
2826 fn update_slice(mut self, inner: Self::Slice) -> Self {
2827 self.input = I::update_slice(self.input, inner);
2828 self
2829 }
2830}
2831
2832impl<I, S> UpdateSlice for Stateful<I, S>
2833where
2834 I: UpdateSlice,
2835 S: Clone + crate::lib::std::fmt::Debug,
2836{
2837 #[inline(always)]
2838 fn update_slice(mut self, inner: Self::Slice) -> Self {
2839 self.input = I::update_slice(self.input, inner);
2840 self
2841 }
2842}
2843
2844impl<I> UpdateSlice for Partial<I>
2845where
2846 I: UpdateSlice,
2847{
2848 #[inline(always)]
2849 fn update_slice(self, inner: Self::Slice) -> Self {
2850 Partial {
2851 input: I::update_slice(self.input, inner),
2852 partial: self.partial,
2853 }
2854 }
2855}
2856
2857/// Ensure checkpoint details are kept private
2858#[derive(Copy, Clone, Debug)]
2859pub struct Checkpoint<T>(T);
2860
2861/// A range bounded inclusively for counting parses performed
2862#[derive(PartialEq, Eq)]
2863pub struct Range {
2864 pub(crate) start_inclusive: usize,
2865 pub(crate) end_inclusive: Option<usize>,
2866}
2867
2868impl Range {
2869 #[inline(always)]
2870 fn raw(start_inclusive: usize, end_inclusive: Option<usize>) -> Self {
2871 Self {
2872 start_inclusive,
2873 end_inclusive,
2874 }
2875 }
2876}
2877
2878impl crate::lib::std::ops::RangeBounds<usize> for Range {
2879 #[inline(always)]
2880 fn start_bound(&self) -> crate::lib::std::ops::Bound<&usize> {
2881 crate::lib::std::ops::Bound::Included(&self.start_inclusive)
2882 }
2883
2884 #[inline(always)]
2885 fn end_bound(&self) -> crate::lib::std::ops::Bound<&usize> {
2886 if let Some(end_inclusive: &usize) = &self.end_inclusive {
2887 crate::lib::std::ops::Bound::Included(end_inclusive)
2888 } else {
2889 crate::lib::std::ops::Bound::Unbounded
2890 }
2891 }
2892}
2893
2894impl From<usize> for Range {
2895 #[inline(always)]
2896 fn from(fixed: usize) -> Self {
2897 (fixed..=fixed).into()
2898 }
2899}
2900
2901impl From<crate::lib::std::ops::Range<usize>> for Range {
2902 #[inline(always)]
2903 fn from(range: crate::lib::std::ops::Range<usize>) -> Self {
2904 let start_inclusive: usize = range.start;
2905 let end_inclusive: Option = Some(range.end.saturating_sub(1));
2906 Self::raw(start_inclusive, end_inclusive)
2907 }
2908}
2909
2910impl From<crate::lib::std::ops::RangeFull> for Range {
2911 #[inline(always)]
2912 fn from(_: crate::lib::std::ops::RangeFull) -> Self {
2913 let start_inclusive: usize = 0;
2914 let end_inclusive: Option = None;
2915 Self::raw(start_inclusive, end_inclusive)
2916 }
2917}
2918
2919impl From<crate::lib::std::ops::RangeFrom<usize>> for Range {
2920 #[inline(always)]
2921 fn from(range: crate::lib::std::ops::RangeFrom<usize>) -> Self {
2922 let start_inclusive: usize = range.start;
2923 let end_inclusive: Option = None;
2924 Self::raw(start_inclusive, end_inclusive)
2925 }
2926}
2927
2928impl From<crate::lib::std::ops::RangeTo<usize>> for Range {
2929 #[inline(always)]
2930 fn from(range: crate::lib::std::ops::RangeTo<usize>) -> Self {
2931 let start_inclusive: usize = 0;
2932 let end_inclusive: Option = Some(range.end.saturating_sub(1));
2933 Self::raw(start_inclusive, end_inclusive)
2934 }
2935}
2936
2937impl From<crate::lib::std::ops::RangeInclusive<usize>> for Range {
2938 #[inline(always)]
2939 fn from(range: crate::lib::std::ops::RangeInclusive<usize>) -> Self {
2940 let start_inclusive: usize = *range.start();
2941 let end_inclusive: Option = Some(*range.end());
2942 Self::raw(start_inclusive, end_inclusive)
2943 }
2944}
2945
2946impl From<crate::lib::std::ops::RangeToInclusive<usize>> for Range {
2947 #[inline(always)]
2948 fn from(range: crate::lib::std::ops::RangeToInclusive<usize>) -> Self {
2949 let start_inclusive: usize = 0;
2950 let end_inclusive: Option = Some(range.end);
2951 Self::raw(start_inclusive, end_inclusive)
2952 }
2953}
2954
2955impl crate::lib::std::fmt::Display for Range {
2956 fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result {
2957 self.start_inclusive.fmt(f)?;
2958 match self.end_inclusive {
2959 Some(e: usize) if e == self.start_inclusive => {}
2960 Some(e: usize) => {
2961 "..=".fmt(f)?;
2962 e.fmt(f)?;
2963 }
2964 None => {
2965 "..".fmt(f)?;
2966 }
2967 }
2968 Ok(())
2969 }
2970}
2971
2972impl crate::lib::std::fmt::Debug for Range {
2973 fn fmt(&self, f: &mut crate::lib::std::fmt::Formatter<'_>) -> crate::lib::std::fmt::Result {
2974 write!(f, "{self}")
2975 }
2976}
2977
2978/// Abstracts something which can extend an `Extend`.
2979/// Used to build modified input slices in `escaped_transform`
2980pub trait Accumulate<T>: Sized {
2981 /// Create a new `Extend` of the correct type
2982 fn initial(capacity: Option<usize>) -> Self;
2983 /// Accumulate the input into an accumulator
2984 fn accumulate(&mut self, acc: T);
2985}
2986
2987impl<T> Accumulate<T> for () {
2988 #[inline(always)]
2989 fn initial(_capacity: Option<usize>) -> Self {}
2990 #[inline(always)]
2991 fn accumulate(&mut self, _acc: T) {}
2992}
2993
2994impl<T> Accumulate<T> for usize {
2995 #[inline(always)]
2996 fn initial(_capacity: Option<usize>) -> Self {
2997 0
2998 }
2999 #[inline(always)]
3000 fn accumulate(&mut self, _acc: T) {
3001 *self += 1;
3002 }
3003}
3004
3005#[cfg(feature = "alloc")]
3006impl<T> Accumulate<T> for Vec<T> {
3007 #[inline(always)]
3008 fn initial(capacity: Option<usize>) -> Self {
3009 match capacity {
3010 Some(capacity: usize) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
3011 None => Vec::new(),
3012 }
3013 }
3014 #[inline(always)]
3015 fn accumulate(&mut self, acc: T) {
3016 self.push(acc);
3017 }
3018}
3019
3020#[cfg(feature = "alloc")]
3021impl<'i, T: Clone> Accumulate<&'i [T]> for Vec<T> {
3022 #[inline(always)]
3023 fn initial(capacity: Option<usize>) -> Self {
3024 match capacity {
3025 Some(capacity: usize) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
3026 None => Vec::new(),
3027 }
3028 }
3029 #[inline(always)]
3030 fn accumulate(&mut self, acc: &'i [T]) {
3031 self.extend(iter:acc.iter().cloned());
3032 }
3033}
3034
3035#[cfg(feature = "alloc")]
3036impl Accumulate<char> for String {
3037 #[inline(always)]
3038 fn initial(capacity: Option<usize>) -> Self {
3039 match capacity {
3040 Some(capacity: usize) => String::with_capacity(clamp_capacity::<char>(capacity)),
3041 None => String::new(),
3042 }
3043 }
3044 #[inline(always)]
3045 fn accumulate(&mut self, acc: char) {
3046 self.push(ch:acc);
3047 }
3048}
3049
3050#[cfg(feature = "alloc")]
3051impl<'i> Accumulate<&'i str> for String {
3052 #[inline(always)]
3053 fn initial(capacity: Option<usize>) -> Self {
3054 match capacity {
3055 Some(capacity: usize) => String::with_capacity(clamp_capacity::<char>(capacity)),
3056 None => String::new(),
3057 }
3058 }
3059 #[inline(always)]
3060 fn accumulate(&mut self, acc: &'i str) {
3061 self.push_str(string:acc);
3062 }
3063}
3064
3065#[cfg(feature = "alloc")]
3066impl<K, V> Accumulate<(K, V)> for BTreeMap<K, V>
3067where
3068 K: crate::lib::std::cmp::Ord,
3069{
3070 #[inline(always)]
3071 fn initial(_capacity: Option<usize>) -> Self {
3072 BTreeMap::new()
3073 }
3074 #[inline(always)]
3075 fn accumulate(&mut self, (key: K, value: V): (K, V)) {
3076 self.insert(key, value);
3077 }
3078}
3079
3080#[cfg(feature = "std")]
3081impl<K, V, S> Accumulate<(K, V)> for HashMap<K, V, S>
3082where
3083 K: crate::lib::std::cmp::Eq + crate::lib::std::hash::Hash,
3084 S: BuildHasher + Default,
3085{
3086 #[inline(always)]
3087 fn initial(capacity: Option<usize>) -> Self {
3088 let h: S = S::default();
3089 match capacity {
3090 Some(capacity: usize) => {
3091 HashMap::with_capacity_and_hasher(capacity:clamp_capacity::<(K, V)>(capacity), hasher:h)
3092 }
3093 None => HashMap::with_hasher(hash_builder:h),
3094 }
3095 }
3096 #[inline(always)]
3097 fn accumulate(&mut self, (key: K, value: V): (K, V)) {
3098 self.insert(k:key, v:value);
3099 }
3100}
3101
3102#[cfg(feature = "alloc")]
3103impl<K> Accumulate<K> for BTreeSet<K>
3104where
3105 K: crate::lib::std::cmp::Ord,
3106{
3107 #[inline(always)]
3108 fn initial(_capacity: Option<usize>) -> Self {
3109 BTreeSet::new()
3110 }
3111 #[inline(always)]
3112 fn accumulate(&mut self, key: K) {
3113 self.insert(key);
3114 }
3115}
3116
3117#[cfg(feature = "std")]
3118impl<K, S> Accumulate<K> for HashSet<K, S>
3119where
3120 K: crate::lib::std::cmp::Eq + crate::lib::std::hash::Hash,
3121 S: BuildHasher + Default,
3122{
3123 #[inline(always)]
3124 fn initial(capacity: Option<usize>) -> Self {
3125 let h: S = S::default();
3126 match capacity {
3127 Some(capacity: usize) => HashSet::with_capacity_and_hasher(capacity:clamp_capacity::<K>(capacity), hasher:h),
3128 None => HashSet::with_hasher(h),
3129 }
3130 }
3131 #[inline(always)]
3132 fn accumulate(&mut self, key: K) {
3133 self.insert(key);
3134 }
3135}
3136
3137#[cfg(feature = "alloc")]
3138#[inline]
3139pub(crate) fn clamp_capacity<T>(capacity: usize) -> usize {
3140 /// Don't pre-allocate more than 64KiB when calling `Vec::with_capacity`.
3141 ///
3142 /// Pre-allocating memory is a nice optimization but count fields can't
3143 /// always be trusted. We should clamp initial capacities to some reasonable
3144 /// amount. This reduces the risk of a bogus count value triggering a panic
3145 /// due to an OOM error.
3146 ///
3147 /// This does not affect correctness. `winnow` will always read the full number
3148 /// of elements regardless of the capacity cap.
3149 const MAX_INITIAL_CAPACITY_BYTES: usize = 65536;
3150
3151 let max_initial_capacity: usize =
3152 MAX_INITIAL_CAPACITY_BYTES / crate::lib::std::mem::size_of::<T>().max(1);
3153 capacity.min(max_initial_capacity)
3154}
3155
3156/// Helper trait to convert numbers to usize.
3157///
3158/// By default, usize implements `From<u8>` and `From<u16>` but not
3159/// `From<u32>` and `From<u64>` because that would be invalid on some
3160/// platforms. This trait implements the conversion for platforms
3161/// with 32 and 64 bits pointer platforms
3162pub trait ToUsize {
3163 /// converts self to usize
3164 fn to_usize(&self) -> usize;
3165}
3166
3167impl ToUsize for u8 {
3168 #[inline(always)]
3169 fn to_usize(&self) -> usize {
3170 *self as usize
3171 }
3172}
3173
3174impl ToUsize for u16 {
3175 #[inline(always)]
3176 fn to_usize(&self) -> usize {
3177 *self as usize
3178 }
3179}
3180
3181impl ToUsize for usize {
3182 #[inline(always)]
3183 fn to_usize(&self) -> usize {
3184 *self
3185 }
3186}
3187
3188#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
3189impl ToUsize for u32 {
3190 #[inline(always)]
3191 fn to_usize(&self) -> usize {
3192 *self as usize
3193 }
3194}
3195
3196#[cfg(target_pointer_width = "64")]
3197impl ToUsize for u64 {
3198 #[inline(always)]
3199 fn to_usize(&self) -> usize {
3200 *self as usize
3201 }
3202}
3203
3204/// Transforms a token into a char for basic string parsing
3205#[allow(clippy::len_without_is_empty)]
3206#[allow(clippy::wrong_self_convention)]
3207pub trait AsChar {
3208 /// Makes a char from self
3209 ///
3210 /// # Example
3211 ///
3212 /// ```
3213 /// use winnow::stream::AsChar as _;
3214 ///
3215 /// assert_eq!('a'.as_char(), 'a');
3216 /// assert_eq!(u8::MAX.as_char(), std::char::from_u32(u8::MAX as u32).unwrap());
3217 /// ```
3218 fn as_char(self) -> char;
3219
3220 /// Tests that self is an alphabetic character
3221 ///
3222 /// **Warning:** for `&str` it recognizes alphabetic
3223 /// characters outside of the 52 ASCII letters
3224 fn is_alpha(self) -> bool;
3225
3226 /// Tests that self is an alphabetic character
3227 /// or a decimal digit
3228 fn is_alphanum(self) -> bool;
3229 /// Tests that self is a decimal digit
3230 fn is_dec_digit(self) -> bool;
3231 /// Tests that self is an hex digit
3232 fn is_hex_digit(self) -> bool;
3233 /// Tests that self is an octal digit
3234 fn is_oct_digit(self) -> bool;
3235 /// Gets the len in bytes for self
3236 fn len(self) -> usize;
3237 /// Tests that self is ASCII space or tab
3238 fn is_space(self) -> bool;
3239 /// Tests if byte is ASCII newline: \n
3240 fn is_newline(self) -> bool;
3241}
3242
3243impl AsChar for u8 {
3244 #[inline(always)]
3245 fn as_char(self) -> char {
3246 self as char
3247 }
3248 #[inline]
3249 fn is_alpha(self) -> bool {
3250 matches!(self, 0x41..=0x5A | 0x61..=0x7A)
3251 }
3252 #[inline]
3253 fn is_alphanum(self) -> bool {
3254 self.is_alpha() || self.is_dec_digit()
3255 }
3256 #[inline]
3257 fn is_dec_digit(self) -> bool {
3258 matches!(self, 0x30..=0x39)
3259 }
3260 #[inline]
3261 fn is_hex_digit(self) -> bool {
3262 matches!(self, 0x30..=0x39 | 0x41..=0x46 | 0x61..=0x66)
3263 }
3264 #[inline]
3265 fn is_oct_digit(self) -> bool {
3266 matches!(self, 0x30..=0x37)
3267 }
3268 #[inline]
3269 fn len(self) -> usize {
3270 1
3271 }
3272 #[inline]
3273 fn is_space(self) -> bool {
3274 self == b' ' || self == b'\t'
3275 }
3276 #[inline]
3277 fn is_newline(self) -> bool {
3278 self == b'\n'
3279 }
3280}
3281
3282impl<'a> AsChar for &'a u8 {
3283 #[inline(always)]
3284 fn as_char(self) -> char {
3285 *self as char
3286 }
3287 #[inline]
3288 fn is_alpha(self) -> bool {
3289 matches!(*self, 0x41..=0x5A | 0x61..=0x7A)
3290 }
3291 #[inline]
3292 fn is_alphanum(self) -> bool {
3293 self.is_alpha() || self.is_dec_digit()
3294 }
3295 #[inline]
3296 fn is_dec_digit(self) -> bool {
3297 matches!(*self, 0x30..=0x39)
3298 }
3299 #[inline]
3300 fn is_hex_digit(self) -> bool {
3301 matches!(*self, 0x30..=0x39 | 0x41..=0x46 | 0x61..=0x66)
3302 }
3303 #[inline]
3304 fn is_oct_digit(self) -> bool {
3305 matches!(*self, 0x30..=0x37)
3306 }
3307 #[inline]
3308 fn len(self) -> usize {
3309 1
3310 }
3311 #[inline]
3312 fn is_space(self) -> bool {
3313 *self == b' ' || *self == b'\t'
3314 }
3315 #[inline]
3316 fn is_newline(self) -> bool {
3317 *self == b'\n'
3318 }
3319}
3320
3321impl AsChar for char {
3322 #[inline(always)]
3323 fn as_char(self) -> char {
3324 self
3325 }
3326 #[inline]
3327 fn is_alpha(self) -> bool {
3328 self.is_ascii_alphabetic()
3329 }
3330 #[inline]
3331 fn is_alphanum(self) -> bool {
3332 self.is_alpha() || self.is_dec_digit()
3333 }
3334 #[inline]
3335 fn is_dec_digit(self) -> bool {
3336 self.is_ascii_digit()
3337 }
3338 #[inline]
3339 fn is_hex_digit(self) -> bool {
3340 self.is_ascii_hexdigit()
3341 }
3342 #[inline]
3343 fn is_oct_digit(self) -> bool {
3344 self.is_digit(8)
3345 }
3346 #[inline]
3347 fn len(self) -> usize {
3348 self.len_utf8()
3349 }
3350 #[inline]
3351 fn is_space(self) -> bool {
3352 self == ' ' || self == '\t'
3353 }
3354 #[inline]
3355 fn is_newline(self) -> bool {
3356 self == '\n'
3357 }
3358}
3359
3360impl<'a> AsChar for &'a char {
3361 #[inline(always)]
3362 fn as_char(self) -> char {
3363 *self
3364 }
3365 #[inline]
3366 fn is_alpha(self) -> bool {
3367 self.is_ascii_alphabetic()
3368 }
3369 #[inline]
3370 fn is_alphanum(self) -> bool {
3371 self.is_alpha() || self.is_dec_digit()
3372 }
3373 #[inline]
3374 fn is_dec_digit(self) -> bool {
3375 self.is_ascii_digit()
3376 }
3377 #[inline]
3378 fn is_hex_digit(self) -> bool {
3379 self.is_ascii_hexdigit()
3380 }
3381 #[inline]
3382 fn is_oct_digit(self) -> bool {
3383 self.is_digit(8)
3384 }
3385 #[inline]
3386 fn len(self) -> usize {
3387 self.len_utf8()
3388 }
3389 #[inline]
3390 fn is_space(self) -> bool {
3391 *self == ' ' || *self == '\t'
3392 }
3393 #[inline]
3394 fn is_newline(self) -> bool {
3395 *self == '\n'
3396 }
3397}
3398
3399/// Check if a token in in a set of possible tokens
3400///
3401/// This is generally implemented on patterns that a token may match and supports `u8` and `char`
3402/// tokens along with the following patterns
3403/// - `b'c'` and `'c'`
3404/// - `b""` and `""`
3405/// - `|c| true`
3406/// - `b'a'..=b'z'`, `'a'..='z'` (etc for each [range type][std::ops])
3407/// - `(pattern1, pattern2, ...)`
3408///
3409/// # Example
3410///
3411/// For example, you could implement `hex_digit0` as:
3412/// ```
3413/// # use winnow::prelude::*;
3414/// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError};
3415/// # use winnow::token::take_while;
3416/// fn hex_digit1<'s>(input: &mut &'s str) -> PResult<&'s str, InputError<&'s str>> {
3417/// take_while(1.., ('a'..='f', 'A'..='F', '0'..='9')).parse_next(input)
3418/// }
3419///
3420/// assert_eq!(hex_digit1.parse_peek("21cZ"), Ok(("Z", "21c")));
3421/// assert_eq!(hex_digit1.parse_peek("H2"), Err(ErrMode::Backtrack(InputError::new("H2", ErrorKind::Slice))));
3422/// assert_eq!(hex_digit1.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Slice))));
3423/// ```
3424pub trait ContainsToken<T> {
3425 /// Returns true if self contains the token
3426 fn contains_token(&self, token: T) -> bool;
3427}
3428
3429impl ContainsToken<u8> for u8 {
3430 #[inline(always)]
3431 fn contains_token(&self, token: u8) -> bool {
3432 *self == token
3433 }
3434}
3435
3436impl<'a> ContainsToken<&'a u8> for u8 {
3437 #[inline(always)]
3438 fn contains_token(&self, token: &u8) -> bool {
3439 self.contains_token(*token)
3440 }
3441}
3442
3443impl ContainsToken<char> for u8 {
3444 #[inline(always)]
3445 fn contains_token(&self, token: char) -> bool {
3446 self.as_char() == token
3447 }
3448}
3449
3450impl<'a> ContainsToken<&'a char> for u8 {
3451 #[inline(always)]
3452 fn contains_token(&self, token: &char) -> bool {
3453 self.contains_token(*token)
3454 }
3455}
3456
3457impl<C: AsChar> ContainsToken<C> for char {
3458 #[inline(always)]
3459 fn contains_token(&self, token: C) -> bool {
3460 *self == token.as_char()
3461 }
3462}
3463
3464impl<C, F: Fn(C) -> bool> ContainsToken<C> for F {
3465 #[inline(always)]
3466 fn contains_token(&self, token: C) -> bool {
3467 self(token)
3468 }
3469}
3470
3471impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::Range<C2> {
3472 #[inline(always)]
3473 fn contains_token(&self, token: C1) -> bool {
3474 let start: char = self.start.clone().as_char();
3475 let end: char = self.end.clone().as_char();
3476 (start..end).contains(&token.as_char())
3477 }
3478}
3479
3480impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1>
3481 for crate::lib::std::ops::RangeInclusive<C2>
3482{
3483 #[inline(always)]
3484 fn contains_token(&self, token: C1) -> bool {
3485 let start: char = self.start().clone().as_char();
3486 let end: char = self.end().clone().as_char();
3487 (start..=end).contains(&token.as_char())
3488 }
3489}
3490
3491impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::RangeFrom<C2> {
3492 #[inline(always)]
3493 fn contains_token(&self, token: C1) -> bool {
3494 let start: char = self.start.clone().as_char();
3495 (start..).contains(&token.as_char())
3496 }
3497}
3498
3499impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for crate::lib::std::ops::RangeTo<C2> {
3500 #[inline(always)]
3501 fn contains_token(&self, token: C1) -> bool {
3502 let end: char = self.end.clone().as_char();
3503 (..end).contains(&token.as_char())
3504 }
3505}
3506
3507impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1>
3508 for crate::lib::std::ops::RangeToInclusive<C2>
3509{
3510 #[inline(always)]
3511 fn contains_token(&self, token: C1) -> bool {
3512 let end: char = self.end.clone().as_char();
3513 (..=end).contains(&token.as_char())
3514 }
3515}
3516
3517impl<C1: AsChar> ContainsToken<C1> for crate::lib::std::ops::RangeFull {
3518 #[inline(always)]
3519 fn contains_token(&self, _token: C1) -> bool {
3520 true
3521 }
3522}
3523
3524impl<C: AsChar> ContainsToken<C> for &'_ [u8] {
3525 #[inline]
3526 fn contains_token(&self, token: C) -> bool {
3527 let token: char = token.as_char();
3528 self.iter().any(|t: &u8| t.as_char() == token)
3529 }
3530}
3531
3532impl<C: AsChar> ContainsToken<C> for &'_ [char] {
3533 #[inline]
3534 fn contains_token(&self, token: C) -> bool {
3535 let token: char = token.as_char();
3536 self.iter().any(|t: &char| *t == token)
3537 }
3538}
3539
3540impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [u8; LEN] {
3541 #[inline]
3542 fn contains_token(&self, token: C) -> bool {
3543 let token: char = token.as_char();
3544 self.iter().any(|t: &u8| t.as_char() == token)
3545 }
3546}
3547
3548impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [char; LEN] {
3549 #[inline]
3550 fn contains_token(&self, token: C) -> bool {
3551 let token: char = token.as_char();
3552 self.iter().any(|t: &char| *t == token)
3553 }
3554}
3555
3556impl<const LEN: usize, C: AsChar> ContainsToken<C> for [u8; LEN] {
3557 #[inline]
3558 fn contains_token(&self, token: C) -> bool {
3559 let token: char = token.as_char();
3560 self.iter().any(|t: &u8| t.as_char() == token)
3561 }
3562}
3563
3564impl<const LEN: usize, C: AsChar> ContainsToken<C> for [char; LEN] {
3565 #[inline]
3566 fn contains_token(&self, token: C) -> bool {
3567 let token: char = token.as_char();
3568 self.iter().any(|t: &char| *t == token)
3569 }
3570}
3571
3572impl<T> ContainsToken<T> for () {
3573 #[inline(always)]
3574 fn contains_token(&self, _token: T) -> bool {
3575 false
3576 }
3577}
3578
3579macro_rules! impl_contains_token_for_tuple {
3580 ($($haystack:ident),+) => (
3581 #[allow(non_snake_case)]
3582 impl<T, $($haystack),+> ContainsToken<T> for ($($haystack),+,)
3583 where
3584 T: Clone,
3585 $($haystack: ContainsToken<T>),+
3586 {
3587 #[inline]
3588 fn contains_token(&self, token: T) -> bool {
3589 let ($(ref $haystack),+,) = *self;
3590 $($haystack.contains_token(token.clone()) || )+ false
3591 }
3592 }
3593 )
3594}
3595
3596macro_rules! impl_contains_token_for_tuples {
3597 ($haystack1:ident, $($haystack:ident),+) => {
3598 impl_contains_token_for_tuples!(__impl $haystack1; $($haystack),+);
3599 };
3600 (__impl $($haystack:ident),+; $haystack1:ident $(,$haystack2:ident)*) => {
3601 impl_contains_token_for_tuple!($($haystack),+);
3602 impl_contains_token_for_tuples!(__impl $($haystack),+, $haystack1; $($haystack2),*);
3603 };
3604 (__impl $($haystack:ident),+;) => {
3605 impl_contains_token_for_tuple!($($haystack),+);
3606 }
3607}
3608
3609impl_contains_token_for_tuples!(
3610 F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21
3611);
3612
3613#[cfg(feature = "simd")]
3614#[inline(always)]
3615fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
3616 memchr::memchr(token, slice)
3617}
3618
3619#[cfg(feature = "simd")]
3620#[inline(always)]
3621fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
3622 memchr::memchr2(token.0, token.1, slice)
3623}
3624
3625#[cfg(feature = "simd")]
3626#[inline(always)]
3627fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
3628 memchr::memchr3(token.0, token.1, token.2, slice)
3629}
3630
3631#[cfg(not(feature = "simd"))]
3632#[inline(always)]
3633fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
3634 slice.iter().position(|t: &u8| *t == token)
3635}
3636
3637#[cfg(not(feature = "simd"))]
3638#[inline(always)]
3639fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
3640 slice.iter().position(|t: &u8| *t == token.0 || *t == token.1)
3641}
3642
3643#[cfg(not(feature = "simd"))]
3644#[inline(always)]
3645fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
3646 sliceIter<'_, u8>
3647 .iter()
3648 .position(|t: &u8| *t == token.0 || *t == token.1 || *t == token.2)
3649}
3650
3651#[inline(always)]
3652fn memmem(slice: &[u8], tag: &[u8]) -> Option<usize> {
3653 if tag.len() == 1 {
3654 memchr(token:tag[0], slice)
3655 } else {
3656 memmem_(slice, tag)
3657 }
3658}
3659
3660#[inline(always)]
3661fn memmem2(slice: &[u8], tag: (&[u8], &[u8])) -> Option<usize> {
3662 if tag.0.len() == 1 && tag.1.len() == 1 {
3663 memchr2((tag.0[0], tag.1[0]), slice)
3664 } else {
3665 memmem2_(slice, tag)
3666 }
3667}
3668
3669#[inline(always)]
3670fn memmem3(slice: &[u8], tag: (&[u8], &[u8], &[u8])) -> Option<usize> {
3671 if tag.0.len() == 1 && tag.1.len() == 1 && tag.2.len() == 1 {
3672 memchr3((tag.0[0], tag.1[0], tag.2[0]), slice)
3673 } else {
3674 memmem3_(slice, tag)
3675 }
3676}
3677
3678#[cfg(feature = "simd")]
3679#[inline(always)]
3680fn memmem_(slice: &[u8], tag: &[u8]) -> Option<usize> {
3681 let &prefix = match tag.first() {
3682 Some(x) => x,
3683 None => return Some(0),
3684 };
3685 #[allow(clippy::manual_find)] // faster this way
3686 for i in memchr::memchr_iter(prefix, slice) {
3687 if slice[i..].starts_with(tag) {
3688 return Some(i);
3689 }
3690 }
3691 None
3692}
3693
3694#[cfg(feature = "simd")]
3695fn memmem2_(slice: &[u8], tag: (&[u8], &[u8])) -> Option<usize> {
3696 let prefix = match (tag.0.first(), tag.1.first()) {
3697 (Some(&a), Some(&b)) => (a, b),
3698 _ => return Some(0),
3699 };
3700 #[allow(clippy::manual_find)] // faster this way
3701 for i in memchr::memchr2_iter(prefix.0, prefix.1, slice) {
3702 let subslice = &slice[i..];
3703 if subslice.starts_with(tag.0) {
3704 return Some(i);
3705 }
3706 if subslice.starts_with(tag.1) {
3707 return Some(i);
3708 }
3709 }
3710 None
3711}
3712
3713#[cfg(feature = "simd")]
3714fn memmem3_(slice: &[u8], tag: (&[u8], &[u8], &[u8])) -> Option<usize> {
3715 let prefix = match (tag.0.first(), tag.1.first(), tag.2.first()) {
3716 (Some(&a), Some(&b), Some(&c)) => (a, b, c),
3717 _ => return Some(0),
3718 };
3719 #[allow(clippy::manual_find)] // faster this way
3720 for i in memchr::memchr3_iter(prefix.0, prefix.1, prefix.2, slice) {
3721 let subslice = &slice[i..];
3722 if subslice.starts_with(tag.0) {
3723 return Some(i);
3724 }
3725 if subslice.starts_with(tag.1) {
3726 return Some(i);
3727 }
3728 if subslice.starts_with(tag.2) {
3729 return Some(i);
3730 }
3731 }
3732 None
3733}
3734
3735#[cfg(not(feature = "simd"))]
3736fn memmem_(slice: &[u8], tag: &[u8]) -> Option<usize> {
3737 for i: usize in 0..slice.len() {
3738 let subslice: &[u8] = &slice[i..];
3739 if subslice.starts_with(needle:tag) {
3740 return Some(i);
3741 }
3742 }
3743 None
3744}
3745
3746#[cfg(not(feature = "simd"))]
3747fn memmem2_(slice: &[u8], tag: (&[u8], &[u8])) -> Option<usize> {
3748 for i: usize in 0..slice.len() {
3749 let subslice: &[u8] = &slice[i..];
3750 if subslice.starts_with(needle:tag.0) {
3751 return Some(i);
3752 }
3753 if subslice.starts_with(needle:tag.1) {
3754 return Some(i);
3755 }
3756 }
3757 None
3758}
3759
3760#[cfg(not(feature = "simd"))]
3761fn memmem3_(slice: &[u8], tag: (&[u8], &[u8], &[u8])) -> Option<usize> {
3762 for i: usize in 0..slice.len() {
3763 let subslice: &[u8] = &slice[i..];
3764 if subslice.starts_with(needle:tag.0) {
3765 return Some(i);
3766 }
3767 if subslice.starts_with(needle:tag.1) {
3768 return Some(i);
3769 }
3770 if subslice.starts_with(needle:tag.2) {
3771 return Some(i);
3772 }
3773 }
3774 None
3775}
3776