1use core::hash::BuildHasher;
13use core::iter::{Cloned, Enumerate};
14use core::num::NonZeroUsize;
15use core::slice::Iter;
16use core::str::from_utf8;
17use core::str::CharIndices;
18use core::str::FromStr;
19
20#[allow(unused_imports)]
21#[cfg(any(feature = "unstable-doc", feature = "unstable-recover"))]
22use crate::error::ErrMode;
23
24#[cfg(feature = "alloc")]
25use alloc::borrow::Cow;
26#[cfg(feature = "alloc")]
27use alloc::collections::BTreeMap;
28#[cfg(feature = "alloc")]
29use alloc::collections::BTreeSet;
30#[cfg(feature = "alloc")]
31use alloc::collections::VecDeque;
32#[cfg(feature = "alloc")]
33use alloc::string::String;
34#[cfg(feature = "alloc")]
35use alloc::vec::Vec;
36#[cfg(feature = "std")]
37use std::collections::HashMap;
38#[cfg(feature = "std")]
39use std::collections::HashSet;
40
41mod bstr;
42mod bytes;
43mod locating;
44mod partial;
45mod range;
46#[cfg(feature = "unstable-recover")]
47#[cfg(feature = "std")]
48mod recoverable;
49mod stateful;
50#[cfg(test)]
51mod tests;
52mod token;
53
54pub use bstr::BStr;
55pub use bytes::Bytes;
56pub use locating::LocatingSlice;
57pub use partial::Partial;
58pub use range::Range;
59#[cfg(feature = "unstable-recover")]
60#[cfg(feature = "std")]
61pub use recoverable::Recoverable;
62pub use stateful::Stateful;
63pub use token::TokenSlice;
64
65pub type Str<'i> = &'i str;
67
68pub trait SliceLen {
70 fn slice_len(&self) -> usize;
73}
74
75impl<T> SliceLen for &[T] {
76 #[inline(always)]
77 fn slice_len(&self) -> usize {
78 self.len()
79 }
80}
81
82impl<T, const LEN: usize> SliceLen for [T; LEN] {
83 #[inline(always)]
84 fn slice_len(&self) -> usize {
85 self.len()
86 }
87}
88
89impl<T, const LEN: usize> SliceLen for &[T; LEN] {
90 #[inline(always)]
91 fn slice_len(&self) -> usize {
92 self.len()
93 }
94}
95
96impl SliceLen for &str {
97 #[inline(always)]
98 fn slice_len(&self) -> usize {
99 self.len()
100 }
101}
102
103impl SliceLen for u8 {
104 #[inline(always)]
105 fn slice_len(&self) -> usize {
106 1
107 }
108}
109
110impl SliceLen for char {
111 #[inline(always)]
112 fn slice_len(&self) -> usize {
113 self.len_utf8()
114 }
115}
116
117impl<I> SliceLen for (I, usize, usize)
118where
119 I: SliceLen,
120{
121 #[inline(always)]
122 fn slice_len(&self) -> usize {
123 self.0.slice_len() * 8 + self.2 - self.1
124 }
125}
126
127pub trait Stream: Offset<<Self as Stream>::Checkpoint> + core::fmt::Debug {
129 type Token: core::fmt::Debug;
133 type Slice: core::fmt::Debug;
137
138 type IterOffsets: Iterator<Item = (usize, Self::Token)>;
140
141 type Checkpoint: Offset + Clone + core::fmt::Debug;
143
144 fn iter_offsets(&self) -> Self::IterOffsets;
146
147 fn eof_offset(&self) -> usize;
149
150 fn next_token(&mut self) -> Option<Self::Token>;
152 fn peek_token(&self) -> Option<Self::Token>;
154
155 fn offset_for<P>(&self, predicate: P) -> Option<usize>
157 where
158 P: Fn(Self::Token) -> bool;
159 fn offset_at(&self, tokens: usize) -> Result<usize, Needed>;
163 fn next_slice(&mut self, offset: usize) -> Self::Slice;
185 unsafe fn next_slice_unchecked(&mut self, offset: usize) -> Self::Slice {
207 self.next_slice(offset)
209 }
210 fn peek_slice(&self, offset: usize) -> Self::Slice;
212 unsafe fn peek_slice_unchecked(&self, offset: usize) -> Self::Slice {
222 self.peek_slice(offset)
224 }
225
226 #[inline(always)]
228 fn finish(&mut self) -> Self::Slice {
229 self.next_slice(self.eof_offset())
230 }
231 #[inline(always)]
233 fn peek_finish(&self) -> Self::Slice
234 where
235 Self: Clone,
236 {
237 self.peek_slice(self.eof_offset())
238 }
239
240 fn checkpoint(&self) -> Self::Checkpoint;
242 fn reset(&mut self, checkpoint: &Self::Checkpoint);
248
249 fn trace(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result;
251}
252
253#[derive(Debug, PartialEq, Eq, Clone, Copy)]
262pub enum Needed {
263 Unknown,
265 Size(NonZeroUsize),
269}
270
271impl Needed {
272 pub fn new(s: usize) -> Self {
274 match NonZeroUsize::new(s) {
275 Some(sz) => Needed::Size(sz),
276 None => Needed::Unknown,
277 }
278 }
279
280 pub fn is_known(&self) -> bool {
282 *self != Needed::Unknown
283 }
284
285 #[inline]
287 pub fn map<F: Fn(NonZeroUsize) -> usize>(self, f: F) -> Needed {
288 match self {
289 Needed::Unknown => Needed::Unknown,
290 Needed::Size(n) => Needed::new(f(n)),
291 }
292 }
293}
294
295impl<'i, T> Stream for &'i [T]
296where
297 T: Clone + core::fmt::Debug,
298{
299 type Token = T;
300 type Slice = &'i [T];
301
302 type IterOffsets = Enumerate<Cloned<Iter<'i, T>>>;
303
304 type Checkpoint = Checkpoint<Self, Self>;
305
306 #[inline(always)]
307 fn iter_offsets(&self) -> Self::IterOffsets {
308 self.iter().cloned().enumerate()
309 }
310 #[inline(always)]
311 fn eof_offset(&self) -> usize {
312 self.len()
313 }
314
315 #[inline(always)]
316 fn next_token(&mut self) -> Option<Self::Token> {
317 let (token, next) = self.split_first()?;
318 *self = next;
319 Some(token.clone())
320 }
321
322 #[inline(always)]
323 fn peek_token(&self) -> Option<Self::Token> {
324 if self.is_empty() {
325 None
326 } else {
327 Some(self[0].clone())
328 }
329 }
330
331 #[inline(always)]
332 fn offset_for<P>(&self, predicate: P) -> Option<usize>
333 where
334 P: Fn(Self::Token) -> bool,
335 {
336 self.iter().position(|b| predicate(b.clone()))
337 }
338 #[inline(always)]
339 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
340 if let Some(needed) = tokens.checked_sub(self.len()).and_then(NonZeroUsize::new) {
341 Err(Needed::Size(needed))
342 } else {
343 Ok(tokens)
344 }
345 }
346 #[inline(always)]
347 fn next_slice(&mut self, offset: usize) -> Self::Slice {
348 let (slice, next) = self.split_at(offset);
349 *self = next;
350 slice
351 }
352 #[inline(always)]
353 unsafe fn next_slice_unchecked(&mut self, offset: usize) -> Self::Slice {
354 #[cfg(debug_assertions)]
355 self.peek_slice(offset);
356
357 let slice = unsafe { self.get_unchecked(..offset) };
359 let next = unsafe { self.get_unchecked(offset..) };
361 *self = next;
362 slice
363 }
364 #[inline(always)]
365 fn peek_slice(&self, offset: usize) -> Self::Slice {
366 &self[..offset]
367 }
368 #[inline(always)]
369 unsafe fn peek_slice_unchecked(&self, offset: usize) -> Self::Slice {
370 #[cfg(debug_assertions)]
371 self.peek_slice(offset);
372
373 let slice = unsafe { self.get_unchecked(..offset) };
375 slice
376 }
377
378 #[inline(always)]
379 fn checkpoint(&self) -> Self::Checkpoint {
380 Checkpoint::<_, Self>::new(*self)
381 }
382 #[inline(always)]
383 fn reset(&mut self, checkpoint: &Self::Checkpoint) {
384 *self = checkpoint.inner;
385 }
386
387 fn trace(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
388 write!(f, "{self:?}")
389 }
390}
391
392impl<'i> Stream for &'i str {
393 type Token = char;
394 type Slice = &'i str;
395
396 type IterOffsets = CharIndices<'i>;
397
398 type Checkpoint = Checkpoint<Self, Self>;
399
400 #[inline(always)]
401 fn iter_offsets(&self) -> Self::IterOffsets {
402 self.char_indices()
403 }
404 #[inline(always)]
405 fn eof_offset(&self) -> usize {
406 self.len()
407 }
408
409 #[inline(always)]
410 fn next_token(&mut self) -> Option<Self::Token> {
411 let mut iter = self.chars();
412 let c = iter.next()?;
413 *self = iter.as_str();
414 Some(c)
415 }
416
417 #[inline(always)]
418 fn peek_token(&self) -> Option<Self::Token> {
419 self.chars().next()
420 }
421
422 #[inline(always)]
423 fn offset_for<P>(&self, predicate: P) -> Option<usize>
424 where
425 P: Fn(Self::Token) -> bool,
426 {
427 for (o, c) in self.iter_offsets() {
428 if predicate(c) {
429 return Some(o);
430 }
431 }
432 None
433 }
434 #[inline]
435 fn offset_at(&self, tokens: usize) -> Result<usize, Needed> {
436 let mut cnt = 0;
437 for (offset, _) in self.iter_offsets() {
438 if cnt == tokens {
439 return Ok(offset);
440 }
441 cnt += 1;
442 }
443
444 if cnt == tokens {
445 Ok(self.eof_offset())
446 } else {
447 Err(Needed::Unknown)
448 }
449 }
450 #[inline(always)]
451 fn next_slice(&mut self, offset: usize) -> Self::Slice {
452 let (slice, next) = self.split_at(offset);
453 *self = next;
454 slice
455 }
456 #[inline(always)]
457 unsafe fn next_slice_unchecked(&mut self, offset: usize) -> Self::Slice {
458 #[cfg(debug_assertions)]
459 self.peek_slice(offset);
460
461 let slice = unsafe { self.get_unchecked(..offset) };
464 let next = unsafe { self.get_unchecked(offset..) };
467 *self = next;
468 slice
469 }
470 #[inline(always)]
471 fn peek_slice(&self, offset: usize) -> Self::Slice {
472 &self[..offset]
473 }
474 #[inline(always)]
475 unsafe fn peek_slice_unchecked(&self, offset: usize) -> Self::Slice {
476 #[cfg(debug_assertions)]
477 self.peek_slice(offset);
478
479 let slice = unsafe { self.get_unchecked(..offset) };
481 slice
482 }
483
484 #[inline(always)]
485 fn checkpoint(&self) -> Self::Checkpoint {
486 Checkpoint::<_, Self>::new(*self)
487 }
488 #[inline(always)]
489 fn reset(&mut self, checkpoint: &Self::Checkpoint) {
490 *self = checkpoint.inner;
491 }
492
493 fn trace(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
494 write!(f, "{self:#?}")
495 }
496}
497
498pub trait Location {
502 fn previous_token_end(&self) -> usize;
504 fn current_token_start(&self) -> usize;
506}
507
508#[cfg(feature = "unstable-recover")]
512#[cfg(feature = "std")]
513pub trait Recover<E>: Stream {
514 fn record_err(
519 &mut self,
520 token_start: &Self::Checkpoint,
521 err_start: &Self::Checkpoint,
522 err: E,
523 ) -> Result<(), E>;
524
525 fn is_recovery_supported() -> bool;
527}
528
529#[cfg(feature = "unstable-recover")]
530#[cfg(feature = "std")]
531impl<'a, T, E> Recover<E> for &'a [T]
532where
533 &'a [T]: Stream,
534{
535 #[inline(always)]
536 fn record_err(
537 &mut self,
538 _token_start: &Self::Checkpoint,
539 _err_start: &Self::Checkpoint,
540 err: E,
541 ) -> Result<(), E> {
542 Err(err)
543 }
544
545 #[inline(always)]
547 fn is_recovery_supported() -> bool {
548 false
549 }
550}
551
552#[cfg(feature = "unstable-recover")]
553#[cfg(feature = "std")]
554impl<E> Recover<E> for &str {
555 #[inline(always)]
556 fn record_err(
557 &mut self,
558 _token_start: &Self::Checkpoint,
559 _err_start: &Self::Checkpoint,
560 err: E,
561 ) -> Result<(), E> {
562 Err(err)
563 }
564
565 #[inline(always)]
567 fn is_recovery_supported() -> bool {
568 false
569 }
570}
571
572pub trait StreamIsPartial: Sized {
576 type PartialState;
578
579 #[must_use]
581 fn complete(&mut self) -> Self::PartialState;
582
583 fn restore_partial(&mut self, state: Self::PartialState);
585
586 fn is_partial_supported() -> bool;
588
589 #[inline(always)]
591 fn is_partial(&self) -> bool {
592 Self::is_partial_supported()
593 }
594}
595
596impl<T> StreamIsPartial for &[T] {
597 type PartialState = ();
598
599 #[inline]
600 fn complete(&mut self) -> Self::PartialState {}
601
602 #[inline]
603 fn restore_partial(&mut self, _state: Self::PartialState) {}
604
605 #[inline(always)]
606 fn is_partial_supported() -> bool {
607 false
608 }
609}
610
611impl StreamIsPartial for &str {
612 type PartialState = ();
613
614 #[inline]
615 fn complete(&mut self) -> Self::PartialState {
616 }
618
619 #[inline]
620 fn restore_partial(&mut self, _state: Self::PartialState) {}
621
622 #[inline(always)]
623 fn is_partial_supported() -> bool {
624 false
625 }
626}
627
628pub trait Offset<Start = Self> {
630 fn offset_from(&self, start: &Start) -> usize;
639}
640
641impl<T> Offset for &[T] {
642 #[inline]
643 fn offset_from(&self, start: &Self) -> usize {
644 let fst = (*start).as_ptr();
645 let snd = (*self).as_ptr();
646
647 debug_assert!(
648 fst <= snd,
649 "`Offset::offset_from({snd:?}, {fst:?})` only accepts slices of `self`"
650 );
651 (snd as usize - fst as usize) / core::mem::size_of::<T>()
652 }
653}
654
655impl<'a, T> Offset<<&'a [T] as Stream>::Checkpoint> for &'a [T]
656where
657 T: Clone + core::fmt::Debug,
658{
659 #[inline(always)]
660 fn offset_from(&self, other: &<&'a [T] as Stream>::Checkpoint) -> usize {
661 self.checkpoint().offset_from(other)
662 }
663}
664
665impl Offset for &str {
666 #[inline(always)]
667 fn offset_from(&self, start: &Self) -> usize {
668 self.as_bytes().offset_from(&start.as_bytes())
669 }
670}
671
672impl<'a> Offset<<&'a str as Stream>::Checkpoint> for &'a str {
673 #[inline(always)]
674 fn offset_from(&self, other: &<&'a str as Stream>::Checkpoint) -> usize {
675 self.checkpoint().offset_from(other)
676 }
677}
678
679impl<I, S> Offset for Checkpoint<I, S>
680where
681 I: Offset,
682{
683 #[inline(always)]
684 fn offset_from(&self, start: &Self) -> usize {
685 self.inner.offset_from(&start.inner)
686 }
687}
688
689pub trait AsBytes {
691 fn as_bytes(&self) -> &[u8];
693}
694
695impl AsBytes for &[u8] {
696 #[inline(always)]
697 fn as_bytes(&self) -> &[u8] {
698 self
699 }
700}
701
702pub trait AsBStr {
704 fn as_bstr(&self) -> &[u8];
706}
707
708impl AsBStr for &[u8] {
709 #[inline(always)]
710 fn as_bstr(&self) -> &[u8] {
711 self
712 }
713}
714
715impl AsBStr for &str {
716 #[inline(always)]
717 fn as_bstr(&self) -> &[u8] {
718 (*self).as_bytes()
719 }
720}
721
722#[derive(Debug, Eq, PartialEq)]
724pub enum CompareResult {
725 Ok(usize),
731 Incomplete,
733 Error,
735}
736
737pub trait Compare<T> {
739 fn compare(&self, t: T) -> CompareResult;
741}
742
743impl<'b> Compare<&'b [u8]> for &[u8] {
744 #[inline]
745 fn compare(&self, t: &'b [u8]) -> CompareResult {
746 if t.iter().zip(*self).any(|(a, b)| a != b) {
747 CompareResult::Error
748 } else if self.len() < t.slice_len() {
749 CompareResult::Incomplete
750 } else {
751 CompareResult::Ok(t.slice_len())
752 }
753 }
754}
755
756impl<const LEN: usize> Compare<[u8; LEN]> for &[u8] {
757 #[inline(always)]
758 fn compare(&self, t: [u8; LEN]) -> CompareResult {
759 self.compare(&t[..])
760 }
761}
762
763impl<'b, const LEN: usize> Compare<&'b [u8; LEN]> for &[u8] {
764 #[inline(always)]
765 fn compare(&self, t: &'b [u8; LEN]) -> CompareResult {
766 self.compare(&t[..])
767 }
768}
769
770impl<'b> Compare<&'b str> for &[u8] {
771 #[inline(always)]
772 fn compare(&self, t: &'b str) -> CompareResult {
773 self.compare(t.as_bytes())
774 }
775}
776
777impl Compare<u8> for &[u8] {
778 #[inline]
779 fn compare(&self, t: u8) -> CompareResult {
780 match self.first().copied() {
781 Some(c) if t == c => CompareResult::Ok(t.slice_len()),
782 Some(_) => CompareResult::Error,
783 None => CompareResult::Incomplete,
784 }
785 }
786}
787
788impl Compare<char> for &[u8] {
789 #[inline(always)]
790 fn compare(&self, t: char) -> CompareResult {
791 self.compare(t.encode_utf8(&mut [0; 4]).as_bytes())
792 }
793}
794
795impl<'b> Compare<&'b str> for &str {
796 #[inline(always)]
797 fn compare(&self, t: &'b str) -> CompareResult {
798 self.as_bytes().compare(t.as_bytes())
799 }
800}
801
802impl Compare<char> for &str {
803 #[inline(always)]
804 fn compare(&self, t: char) -> CompareResult {
805 self.as_bytes().compare(t)
806 }
807}
808
809pub trait FindSlice<T> {
811 fn find_slice(&self, substr: T) -> Option<core::ops::Range<usize>>;
813}
814
815impl<'s> FindSlice<&'s [u8]> for &[u8] {
816 #[inline(always)]
817 fn find_slice(&self, substr: &'s [u8]) -> Option<core::ops::Range<usize>> {
818 memmem(self, substr)
819 }
820}
821
822impl<'s> FindSlice<(&'s [u8],)> for &[u8] {
823 #[inline(always)]
824 fn find_slice(&self, substr: (&'s [u8],)) -> Option<core::ops::Range<usize>> {
825 memmem(self, substr.0)
826 }
827}
828
829impl<'s> FindSlice<(&'s [u8], &'s [u8])> for &[u8] {
830 #[inline(always)]
831 fn find_slice(&self, substr: (&'s [u8], &'s [u8])) -> Option<core::ops::Range<usize>> {
832 memmem2(self, substr)
833 }
834}
835
836impl<'s> FindSlice<(&'s [u8], &'s [u8], &'s [u8])> for &[u8] {
837 #[inline(always)]
838 fn find_slice(
839 &self,
840 substr: (&'s [u8], &'s [u8], &'s [u8]),
841 ) -> Option<core::ops::Range<usize>> {
842 memmem3(self, substr)
843 }
844}
845
846impl FindSlice<char> for &[u8] {
847 #[inline(always)]
848 fn find_slice(&self, substr: char) -> Option<core::ops::Range<usize>> {
849 let mut b = [0; 4];
850 let substr = substr.encode_utf8(&mut b);
851 self.find_slice(&*substr)
852 }
853}
854
855impl FindSlice<(char,)> for &[u8] {
856 #[inline(always)]
857 fn find_slice(&self, substr: (char,)) -> Option<core::ops::Range<usize>> {
858 let mut b = [0; 4];
859 let substr0 = substr.0.encode_utf8(&mut b);
860 self.find_slice((&*substr0,))
861 }
862}
863
864impl FindSlice<(char, char)> for &[u8] {
865 #[inline(always)]
866 fn find_slice(&self, substr: (char, char)) -> Option<core::ops::Range<usize>> {
867 let mut b = [0; 4];
868 let substr0 = substr.0.encode_utf8(&mut b);
869 let mut b = [0; 4];
870 let substr1 = substr.1.encode_utf8(&mut b);
871 self.find_slice((&*substr0, &*substr1))
872 }
873}
874
875impl FindSlice<(char, char, char)> for &[u8] {
876 #[inline(always)]
877 fn find_slice(&self, substr: (char, char, char)) -> Option<core::ops::Range<usize>> {
878 let mut b = [0; 4];
879 let substr0 = substr.0.encode_utf8(&mut b);
880 let mut b = [0; 4];
881 let substr1 = substr.1.encode_utf8(&mut b);
882 let mut b = [0; 4];
883 let substr2 = substr.2.encode_utf8(&mut b);
884 self.find_slice((&*substr0, &*substr1, &*substr2))
885 }
886}
887
888impl FindSlice<u8> for &[u8] {
889 #[inline(always)]
890 fn find_slice(&self, substr: u8) -> Option<core::ops::Range<usize>> {
891 memchr(substr, self).map(|i| i..i + 1)
892 }
893}
894
895impl FindSlice<(u8,)> for &[u8] {
896 #[inline(always)]
897 fn find_slice(&self, substr: (u8,)) -> Option<core::ops::Range<usize>> {
898 memchr(substr.0, self).map(|i| i..i + 1)
899 }
900}
901
902impl FindSlice<(u8, u8)> for &[u8] {
903 #[inline(always)]
904 fn find_slice(&self, substr: (u8, u8)) -> Option<core::ops::Range<usize>> {
905 memchr2(substr, self).map(|i| i..i + 1)
906 }
907}
908
909impl FindSlice<(u8, u8, u8)> for &[u8] {
910 #[inline(always)]
911 fn find_slice(&self, substr: (u8, u8, u8)) -> Option<core::ops::Range<usize>> {
912 memchr3(substr, self).map(|i| i..i + 1)
913 }
914}
915
916impl<'s> FindSlice<&'s str> for &[u8] {
917 #[inline(always)]
918 fn find_slice(&self, substr: &'s str) -> Option<core::ops::Range<usize>> {
919 self.find_slice(substr.as_bytes())
920 }
921}
922
923impl<'s> FindSlice<(&'s str,)> for &[u8] {
924 #[inline(always)]
925 fn find_slice(&self, substr: (&'s str,)) -> Option<core::ops::Range<usize>> {
926 memmem(self, substr.0.as_bytes())
927 }
928}
929
930impl<'s> FindSlice<(&'s str, &'s str)> for &[u8] {
931 #[inline(always)]
932 fn find_slice(&self, substr: (&'s str, &'s str)) -> Option<core::ops::Range<usize>> {
933 memmem2(self, (substr.0.as_bytes(), substr.1.as_bytes()))
934 }
935}
936
937impl<'s> FindSlice<(&'s str, &'s str, &'s str)> for &[u8] {
938 #[inline(always)]
939 fn find_slice(&self, substr: (&'s str, &'s str, &'s str)) -> Option<core::ops::Range<usize>> {
940 memmem3(
941 self,
942 (
943 substr.0.as_bytes(),
944 substr.1.as_bytes(),
945 substr.2.as_bytes(),
946 ),
947 )
948 }
949}
950
951impl<'s> FindSlice<&'s str> for &str {
952 #[inline(always)]
953 fn find_slice(&self, substr: &'s str) -> Option<core::ops::Range<usize>> {
954 self.as_bytes().find_slice(substr)
955 }
956}
957
958impl<'s> FindSlice<(&'s str,)> for &str {
959 #[inline(always)]
960 fn find_slice(&self, substr: (&'s str,)) -> Option<core::ops::Range<usize>> {
961 self.as_bytes().find_slice(substr)
962 }
963}
964
965impl<'s> FindSlice<(&'s str, &'s str)> for &str {
966 #[inline(always)]
967 fn find_slice(&self, substr: (&'s str, &'s str)) -> Option<core::ops::Range<usize>> {
968 self.as_bytes().find_slice(substr)
969 }
970}
971
972impl<'s> FindSlice<(&'s str, &'s str, &'s str)> for &str {
973 #[inline(always)]
974 fn find_slice(&self, substr: (&'s str, &'s str, &'s str)) -> Option<core::ops::Range<usize>> {
975 self.as_bytes().find_slice(substr)
976 }
977}
978
979impl FindSlice<char> for &str {
980 #[inline(always)]
981 fn find_slice(&self, substr: char) -> Option<core::ops::Range<usize>> {
982 self.as_bytes().find_slice(substr)
983 }
984}
985
986impl FindSlice<(char,)> for &str {
987 #[inline(always)]
988 fn find_slice(&self, substr: (char,)) -> Option<core::ops::Range<usize>> {
989 self.as_bytes().find_slice(substr)
990 }
991}
992
993impl FindSlice<(char, char)> for &str {
994 #[inline(always)]
995 fn find_slice(&self, substr: (char, char)) -> Option<core::ops::Range<usize>> {
996 self.as_bytes().find_slice(substr)
997 }
998}
999
1000impl FindSlice<(char, char, char)> for &str {
1001 #[inline(always)]
1002 fn find_slice(&self, substr: (char, char, char)) -> Option<core::ops::Range<usize>> {
1003 self.as_bytes().find_slice(substr)
1004 }
1005}
1006
1007pub trait ParseSlice<R> {
1009 fn parse_slice(&self) -> Option<R>;
1014}
1015
1016impl<R: FromStr> ParseSlice<R> for &[u8] {
1017 #[inline(always)]
1018 fn parse_slice(&self) -> Option<R> {
1019 from_utf8(self).ok().and_then(|s| s.parse().ok())
1020 }
1021}
1022
1023impl<R: FromStr> ParseSlice<R> for &str {
1024 #[inline(always)]
1025 fn parse_slice(&self) -> Option<R> {
1026 self.parse().ok()
1027 }
1028}
1029
1030pub trait UpdateSlice: Stream {
1032 fn update_slice(self, inner: Self::Slice) -> Self;
1034}
1035
1036impl<T> UpdateSlice for &[T]
1037where
1038 T: Clone + core::fmt::Debug,
1039{
1040 #[inline(always)]
1041 fn update_slice(self, inner: Self::Slice) -> Self {
1042 inner
1043 }
1044}
1045
1046impl UpdateSlice for &str {
1047 #[inline(always)]
1048 fn update_slice(self, inner: Self::Slice) -> Self {
1049 inner
1050 }
1051}
1052
1053pub struct Checkpoint<T, S> {
1055 pub(crate) inner: T,
1056 stream: core::marker::PhantomData<S>,
1057}
1058
1059impl<T, S> Checkpoint<T, S> {
1060 pub(crate) fn new(inner: T) -> Self {
1061 Self {
1062 inner,
1063 stream: Default::default(),
1064 }
1065 }
1066}
1067
1068impl<T: Copy, S> Copy for Checkpoint<T, S> {}
1069
1070impl<T: Clone, S> Clone for Checkpoint<T, S> {
1071 #[inline(always)]
1072 fn clone(&self) -> Self {
1073 Self {
1074 inner: self.inner.clone(),
1075 stream: Default::default(),
1076 }
1077 }
1078}
1079
1080impl<T: PartialOrd, S> PartialOrd for Checkpoint<T, S> {
1081 #[inline(always)]
1082 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1083 self.inner.partial_cmp(&other.inner)
1084 }
1085}
1086
1087impl<T: Ord, S> Ord for Checkpoint<T, S> {
1088 #[inline(always)]
1089 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1090 self.inner.cmp(&other.inner)
1091 }
1092}
1093
1094impl<T: PartialEq, S> PartialEq for Checkpoint<T, S> {
1095 #[inline(always)]
1096 fn eq(&self, other: &Self) -> bool {
1097 self.inner.eq(&other.inner)
1098 }
1099}
1100
1101impl<T: Eq, S> Eq for Checkpoint<T, S> {}
1102
1103impl<T: core::fmt::Debug, S> core::fmt::Debug for Checkpoint<T, S> {
1104 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1105 self.inner.fmt(f)
1106 }
1107}
1108
1109pub trait Accumulate<T>: Sized {
1113 fn initial(capacity: Option<usize>) -> Self;
1115 fn accumulate(&mut self, acc: T);
1117}
1118
1119impl<T> Accumulate<T> for () {
1120 #[inline(always)]
1121 fn initial(_capacity: Option<usize>) -> Self {}
1122 #[inline(always)]
1123 fn accumulate(&mut self, _acc: T) {}
1124}
1125
1126impl<T> Accumulate<T> for usize {
1127 #[inline(always)]
1128 fn initial(_capacity: Option<usize>) -> Self {
1129 0
1130 }
1131 #[inline(always)]
1132 fn accumulate(&mut self, _acc: T) {
1133 *self += 1;
1134 }
1135}
1136
1137#[cfg(feature = "alloc")]
1138impl<T> Accumulate<T> for Vec<T> {
1139 #[inline(always)]
1140 fn initial(capacity: Option<usize>) -> Self {
1141 match capacity {
1142 Some(capacity) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
1143 None => Vec::new(),
1144 }
1145 }
1146 #[inline(always)]
1147 fn accumulate(&mut self, acc: T) {
1148 self.push(acc);
1149 }
1150}
1151
1152#[cfg(feature = "alloc")]
1153impl<'i, T: Clone> Accumulate<&'i [T]> for Vec<T> {
1154 #[inline(always)]
1155 fn initial(capacity: Option<usize>) -> Self {
1156 match capacity {
1157 Some(capacity) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
1158 None => Vec::new(),
1159 }
1160 }
1161 #[inline(always)]
1162 fn accumulate(&mut self, acc: &'i [T]) {
1163 self.extend(acc.iter().cloned());
1164 }
1165}
1166
1167#[cfg(feature = "alloc")]
1168impl Accumulate<char> for String {
1169 #[inline(always)]
1170 fn initial(capacity: Option<usize>) -> Self {
1171 match capacity {
1172 Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1173 None => String::new(),
1174 }
1175 }
1176 #[inline(always)]
1177 fn accumulate(&mut self, acc: char) {
1178 self.push(acc);
1179 }
1180}
1181
1182#[cfg(feature = "alloc")]
1183impl<'i> Accumulate<&'i str> for String {
1184 #[inline(always)]
1185 fn initial(capacity: Option<usize>) -> Self {
1186 match capacity {
1187 Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1188 None => String::new(),
1189 }
1190 }
1191 #[inline(always)]
1192 fn accumulate(&mut self, acc: &'i str) {
1193 self.push_str(acc);
1194 }
1195}
1196
1197#[cfg(feature = "alloc")]
1198impl<'i> Accumulate<Cow<'i, str>> for String {
1199 #[inline(always)]
1200 fn initial(capacity: Option<usize>) -> Self {
1201 match capacity {
1202 Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1203 None => String::new(),
1204 }
1205 }
1206 #[inline(always)]
1207 fn accumulate(&mut self, acc: Cow<'i, str>) {
1208 self.push_str(&acc);
1209 }
1210}
1211
1212#[cfg(feature = "alloc")]
1213impl Accumulate<String> for String {
1214 #[inline(always)]
1215 fn initial(capacity: Option<usize>) -> Self {
1216 match capacity {
1217 Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1218 None => String::new(),
1219 }
1220 }
1221 #[inline(always)]
1222 fn accumulate(&mut self, acc: String) {
1223 self.push_str(&acc);
1224 }
1225}
1226
1227#[cfg(feature = "alloc")]
1228impl Accumulate<char> for Cow<'_, str> {
1229 #[inline(always)]
1230 fn initial(_capacity: Option<usize>) -> Self {
1231 Cow::Borrowed("")
1232 }
1233 #[inline(always)]
1234 fn accumulate(&mut self, acc: char) {
1235 self.to_mut().accumulate(acc);
1236 }
1237}
1238
1239#[cfg(feature = "alloc")]
1240impl<'i> Accumulate<&'i str> for Cow<'i, str> {
1241 #[inline(always)]
1242 fn initial(_capacity: Option<usize>) -> Self {
1243 Cow::Borrowed("")
1244 }
1245 #[inline(always)]
1246 fn accumulate(&mut self, acc: &'i str) {
1247 if self.as_ref().is_empty() {
1248 *self = Cow::Borrowed(acc);
1249 } else {
1250 self.to_mut().accumulate(acc);
1251 }
1252 }
1253}
1254
1255#[cfg(feature = "alloc")]
1256impl<'i> Accumulate<Cow<'i, str>> for Cow<'i, str> {
1257 #[inline(always)]
1258 fn initial(_capacity: Option<usize>) -> Self {
1259 Cow::Borrowed("")
1260 }
1261 #[inline(always)]
1262 fn accumulate(&mut self, acc: Cow<'i, str>) {
1263 if self.as_ref().is_empty() {
1264 *self = acc;
1265 } else {
1266 self.to_mut().accumulate(acc);
1267 }
1268 }
1269}
1270
1271#[cfg(feature = "alloc")]
1272impl Accumulate<String> for Cow<'_, str> {
1273 #[inline(always)]
1274 fn initial(_capacity: Option<usize>) -> Self {
1275 Cow::Borrowed("")
1276 }
1277 #[inline(always)]
1278 fn accumulate(&mut self, acc: String) {
1279 self.to_mut().accumulate(acc);
1280 }
1281}
1282
1283#[cfg(feature = "alloc")]
1284impl<K, V> Accumulate<(K, V)> for BTreeMap<K, V>
1285where
1286 K: core::cmp::Ord,
1287{
1288 #[inline(always)]
1289 fn initial(_capacity: Option<usize>) -> Self {
1290 BTreeMap::new()
1291 }
1292 #[inline(always)]
1293 fn accumulate(&mut self, (key, value): (K, V)) {
1294 self.insert(key, value);
1295 }
1296}
1297
1298#[cfg(feature = "std")]
1299impl<K, V, S> Accumulate<(K, V)> for HashMap<K, V, S>
1300where
1301 K: core::cmp::Eq + core::hash::Hash,
1302 S: BuildHasher + Default,
1303{
1304 #[inline(always)]
1305 fn initial(capacity: Option<usize>) -> Self {
1306 let h = S::default();
1307 match capacity {
1308 Some(capacity) => {
1309 HashMap::with_capacity_and_hasher(clamp_capacity::<(K, V)>(capacity), h)
1310 }
1311 None => HashMap::with_hasher(h),
1312 }
1313 }
1314 #[inline(always)]
1315 fn accumulate(&mut self, (key, value): (K, V)) {
1316 self.insert(key, value);
1317 }
1318}
1319
1320#[cfg(feature = "alloc")]
1321impl<K> Accumulate<K> for BTreeSet<K>
1322where
1323 K: core::cmp::Ord,
1324{
1325 #[inline(always)]
1326 fn initial(_capacity: Option<usize>) -> Self {
1327 BTreeSet::new()
1328 }
1329 #[inline(always)]
1330 fn accumulate(&mut self, key: K) {
1331 self.insert(key);
1332 }
1333}
1334
1335#[cfg(feature = "std")]
1336impl<K, S> Accumulate<K> for HashSet<K, S>
1337where
1338 K: core::cmp::Eq + core::hash::Hash,
1339 S: BuildHasher + Default,
1340{
1341 #[inline(always)]
1342 fn initial(capacity: Option<usize>) -> Self {
1343 let h = S::default();
1344 match capacity {
1345 Some(capacity) => HashSet::with_capacity_and_hasher(clamp_capacity::<K>(capacity), h),
1346 None => HashSet::with_hasher(h),
1347 }
1348 }
1349 #[inline(always)]
1350 fn accumulate(&mut self, key: K) {
1351 self.insert(key);
1352 }
1353}
1354
1355#[cfg(feature = "alloc")]
1356impl<'i, T: Clone> Accumulate<&'i [T]> for VecDeque<T> {
1357 #[inline(always)]
1358 fn initial(capacity: Option<usize>) -> Self {
1359 match capacity {
1360 Some(capacity) => VecDeque::with_capacity(clamp_capacity::<T>(capacity)),
1361 None => VecDeque::new(),
1362 }
1363 }
1364 #[inline(always)]
1365 fn accumulate(&mut self, acc: &'i [T]) {
1366 self.extend(acc.iter().cloned());
1367 }
1368}
1369
1370#[cfg(feature = "alloc")]
1371#[inline]
1372pub(crate) fn clamp_capacity<T>(capacity: usize) -> usize {
1373 const MAX_INITIAL_CAPACITY_BYTES: usize = 65536;
1383
1384 let max_initial_capacity = MAX_INITIAL_CAPACITY_BYTES / core::mem::size_of::<T>().max(1);
1385 capacity.min(max_initial_capacity)
1386}
1387
1388pub trait ToUsize {
1395 fn to_usize(&self) -> usize;
1397}
1398
1399impl ToUsize for u8 {
1400 #[inline(always)]
1401 fn to_usize(&self) -> usize {
1402 *self as usize
1403 }
1404}
1405
1406impl ToUsize for u16 {
1407 #[inline(always)]
1408 fn to_usize(&self) -> usize {
1409 *self as usize
1410 }
1411}
1412
1413impl ToUsize for usize {
1414 #[inline(always)]
1415 fn to_usize(&self) -> usize {
1416 *self
1417 }
1418}
1419
1420#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
1421impl ToUsize for u32 {
1422 #[inline(always)]
1423 fn to_usize(&self) -> usize {
1424 *self as usize
1425 }
1426}
1427
1428#[cfg(target_pointer_width = "64")]
1429impl ToUsize for u64 {
1430 #[inline(always)]
1431 fn to_usize(&self) -> usize {
1432 *self as usize
1433 }
1434}
1435
1436#[allow(clippy::len_without_is_empty)]
1438#[allow(clippy::wrong_self_convention)]
1439pub trait AsChar {
1440 fn as_char(self) -> char;
1451
1452 fn is_alpha(self) -> bool;
1454
1455 fn is_alphanum(self) -> bool;
1458 fn is_dec_digit(self) -> bool;
1460 fn is_hex_digit(self) -> bool;
1462 fn is_oct_digit(self) -> bool;
1464 fn len(self) -> usize;
1466 fn is_space(self) -> bool;
1468 fn is_newline(self) -> bool;
1470}
1471
1472impl AsChar for u8 {
1473 #[inline(always)]
1474 fn as_char(self) -> char {
1475 self as char
1476 }
1477 #[inline]
1478 fn is_alpha(self) -> bool {
1479 matches!(self, 0x41..=0x5A | 0x61..=0x7A)
1480 }
1481 #[inline]
1482 fn is_alphanum(self) -> bool {
1483 self.is_alpha() || self.is_dec_digit()
1484 }
1485 #[inline]
1486 fn is_dec_digit(self) -> bool {
1487 matches!(self, 0x30..=0x39)
1488 }
1489 #[inline]
1490 fn is_hex_digit(self) -> bool {
1491 matches!(self, 0x30..=0x39 | 0x41..=0x46 | 0x61..=0x66)
1492 }
1493 #[inline]
1494 fn is_oct_digit(self) -> bool {
1495 matches!(self, 0x30..=0x37)
1496 }
1497 #[inline]
1498 fn len(self) -> usize {
1499 1
1500 }
1501 #[inline]
1502 fn is_space(self) -> bool {
1503 self == b' ' || self == b'\t'
1504 }
1505 #[inline]
1506 fn is_newline(self) -> bool {
1507 self == b'\n'
1508 }
1509}
1510
1511impl AsChar for &u8 {
1512 #[inline(always)]
1513 fn as_char(self) -> char {
1514 (*self).as_char()
1515 }
1516 #[inline(always)]
1517 fn is_alpha(self) -> bool {
1518 (*self).is_alpha()
1519 }
1520 #[inline(always)]
1521 fn is_alphanum(self) -> bool {
1522 (*self).is_alphanum()
1523 }
1524 #[inline(always)]
1525 fn is_dec_digit(self) -> bool {
1526 (*self).is_dec_digit()
1527 }
1528 #[inline(always)]
1529 fn is_hex_digit(self) -> bool {
1530 (*self).is_hex_digit()
1531 }
1532 #[inline(always)]
1533 fn is_oct_digit(self) -> bool {
1534 (*self).is_oct_digit()
1535 }
1536 #[inline(always)]
1537 fn len(self) -> usize {
1538 (*self).len()
1539 }
1540 #[inline(always)]
1541 fn is_space(self) -> bool {
1542 (*self).is_space()
1543 }
1544 #[inline(always)]
1545 fn is_newline(self) -> bool {
1546 (*self).is_newline()
1547 }
1548}
1549
1550impl AsChar for char {
1551 #[inline(always)]
1552 fn as_char(self) -> char {
1553 self
1554 }
1555 #[inline]
1556 fn is_alpha(self) -> bool {
1557 self.is_ascii_alphabetic()
1558 }
1559 #[inline]
1560 fn is_alphanum(self) -> bool {
1561 self.is_alpha() || self.is_dec_digit()
1562 }
1563 #[inline]
1564 fn is_dec_digit(self) -> bool {
1565 self.is_ascii_digit()
1566 }
1567 #[inline]
1568 fn is_hex_digit(self) -> bool {
1569 self.is_ascii_hexdigit()
1570 }
1571 #[inline]
1572 fn is_oct_digit(self) -> bool {
1573 self.is_digit(8)
1574 }
1575 #[inline]
1576 fn len(self) -> usize {
1577 self.len_utf8()
1578 }
1579 #[inline]
1580 fn is_space(self) -> bool {
1581 self == ' ' || self == '\t'
1582 }
1583 #[inline]
1584 fn is_newline(self) -> bool {
1585 self == '\n'
1586 }
1587}
1588
1589impl AsChar for &char {
1590 #[inline(always)]
1591 fn as_char(self) -> char {
1592 (*self).as_char()
1593 }
1594 #[inline(always)]
1595 fn is_alpha(self) -> bool {
1596 (*self).is_alpha()
1597 }
1598 #[inline(always)]
1599 fn is_alphanum(self) -> bool {
1600 (*self).is_alphanum()
1601 }
1602 #[inline(always)]
1603 fn is_dec_digit(self) -> bool {
1604 (*self).is_dec_digit()
1605 }
1606 #[inline(always)]
1607 fn is_hex_digit(self) -> bool {
1608 (*self).is_hex_digit()
1609 }
1610 #[inline(always)]
1611 fn is_oct_digit(self) -> bool {
1612 (*self).is_oct_digit()
1613 }
1614 #[inline(always)]
1615 fn len(self) -> usize {
1616 (*self).len()
1617 }
1618 #[inline(always)]
1619 fn is_space(self) -> bool {
1620 (*self).is_space()
1621 }
1622 #[inline(always)]
1623 fn is_newline(self) -> bool {
1624 (*self).is_newline()
1625 }
1626}
1627
1628pub trait ContainsToken<T> {
1655 fn contains_token(&self, token: T) -> bool;
1657}
1658
1659impl ContainsToken<u8> for u8 {
1660 #[inline(always)]
1661 fn contains_token(&self, token: u8) -> bool {
1662 *self == token
1663 }
1664}
1665
1666impl ContainsToken<&u8> for u8 {
1667 #[inline(always)]
1668 fn contains_token(&self, token: &u8) -> bool {
1669 self.contains_token(*token)
1670 }
1671}
1672
1673impl ContainsToken<char> for u8 {
1674 #[inline(always)]
1675 fn contains_token(&self, token: char) -> bool {
1676 self.as_char() == token
1677 }
1678}
1679
1680impl ContainsToken<&char> for u8 {
1681 #[inline(always)]
1682 fn contains_token(&self, token: &char) -> bool {
1683 self.contains_token(*token)
1684 }
1685}
1686
1687impl<C: AsChar> ContainsToken<C> for char {
1688 #[inline(always)]
1689 fn contains_token(&self, token: C) -> bool {
1690 *self == token.as_char()
1691 }
1692}
1693
1694impl<C, F: Fn(C) -> bool> ContainsToken<C> for F {
1695 #[inline(always)]
1696 fn contains_token(&self, token: C) -> bool {
1697 self(token)
1698 }
1699}
1700
1701impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::Range<C2> {
1702 #[inline(always)]
1703 fn contains_token(&self, token: C1) -> bool {
1704 let start = self.start.clone().as_char();
1705 let end = self.end.clone().as_char();
1706 (start..end).contains(&token.as_char())
1707 }
1708}
1709
1710impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeInclusive<C2> {
1711 #[inline(always)]
1712 fn contains_token(&self, token: C1) -> bool {
1713 let start = self.start().clone().as_char();
1714 let end = self.end().clone().as_char();
1715 (start..=end).contains(&token.as_char())
1716 }
1717}
1718
1719impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeFrom<C2> {
1720 #[inline(always)]
1721 fn contains_token(&self, token: C1) -> bool {
1722 let start = self.start.clone().as_char();
1723 (start..).contains(&token.as_char())
1724 }
1725}
1726
1727impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeTo<C2> {
1728 #[inline(always)]
1729 fn contains_token(&self, token: C1) -> bool {
1730 let end = self.end.clone().as_char();
1731 (..end).contains(&token.as_char())
1732 }
1733}
1734
1735impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeToInclusive<C2> {
1736 #[inline(always)]
1737 fn contains_token(&self, token: C1) -> bool {
1738 let end = self.end.clone().as_char();
1739 (..=end).contains(&token.as_char())
1740 }
1741}
1742
1743impl<C1: AsChar> ContainsToken<C1> for core::ops::RangeFull {
1744 #[inline(always)]
1745 fn contains_token(&self, _token: C1) -> bool {
1746 true
1747 }
1748}
1749
1750impl<C: AsChar> ContainsToken<C> for &'_ [u8] {
1751 #[inline]
1752 fn contains_token(&self, token: C) -> bool {
1753 let token = token.as_char();
1754 self.iter().any(|t| t.as_char() == token)
1755 }
1756}
1757
1758impl<C: AsChar> ContainsToken<C> for &'_ [char] {
1759 #[inline]
1760 fn contains_token(&self, token: C) -> bool {
1761 let token = token.as_char();
1762 self.contains(&token)
1763 }
1764}
1765
1766impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [u8; LEN] {
1767 #[inline]
1768 fn contains_token(&self, token: C) -> bool {
1769 let token = token.as_char();
1770 self.iter().any(|t| t.as_char() == token)
1771 }
1772}
1773
1774impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [char; LEN] {
1775 #[inline]
1776 fn contains_token(&self, token: C) -> bool {
1777 let token = token.as_char();
1778 self.contains(&token)
1779 }
1780}
1781
1782impl<const LEN: usize, C: AsChar> ContainsToken<C> for [u8; LEN] {
1783 #[inline]
1784 fn contains_token(&self, token: C) -> bool {
1785 let token = token.as_char();
1786 self.iter().any(|t| t.as_char() == token)
1787 }
1788}
1789
1790impl<const LEN: usize, C: AsChar> ContainsToken<C> for [char; LEN] {
1791 #[inline]
1792 fn contains_token(&self, token: C) -> bool {
1793 let token = token.as_char();
1794 self.contains(&token)
1795 }
1796}
1797
1798impl<T> ContainsToken<T> for () {
1799 #[inline(always)]
1800 fn contains_token(&self, _token: T) -> bool {
1801 false
1802 }
1803}
1804
1805macro_rules! impl_contains_token_for_tuple {
1806 ($($haystack:ident),+) => (
1807 #[allow(non_snake_case)]
1808 impl<T, $($haystack),+> ContainsToken<T> for ($($haystack),+,)
1809 where
1810 T: Clone,
1811 $($haystack: ContainsToken<T>),+
1812 {
1813 #[inline]
1814 fn contains_token(&self, token: T) -> bool {
1815 let ($(ref $haystack),+,) = *self;
1816 $($haystack.contains_token(token.clone()) || )+ false
1817 }
1818 }
1819 )
1820}
1821
1822macro_rules! impl_contains_token_for_tuples {
1823 ($haystack1:ident, $($haystack:ident),+) => {
1824 impl_contains_token_for_tuples!(__impl $haystack1; $($haystack),+);
1825 };
1826 (__impl $($haystack:ident),+; $haystack1:ident $(,$haystack2:ident)*) => {
1827 impl_contains_token_for_tuple!($($haystack),+);
1828 impl_contains_token_for_tuples!(__impl $($haystack),+, $haystack1; $($haystack2),*);
1829 };
1830 (__impl $($haystack:ident),+;) => {
1831 impl_contains_token_for_tuple!($($haystack),+);
1832 }
1833}
1834
1835impl_contains_token_for_tuples!(F1, F2, F3, F4, F5, F6, F7, F8, F9, F10);
1836
1837#[cfg(feature = "simd")]
1838#[inline(always)]
1839fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
1840 memchr::memchr(token, slice)
1841}
1842
1843#[cfg(feature = "simd")]
1844#[inline(always)]
1845fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
1846 memchr::memchr2(token.0, token.1, slice)
1847}
1848
1849#[cfg(feature = "simd")]
1850#[inline(always)]
1851fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
1852 memchr::memchr3(token.0, token.1, token.2, slice)
1853}
1854
1855#[cfg(not(feature = "simd"))]
1856#[inline(always)]
1857fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
1858 slice.iter().position(|t| *t == token)
1859}
1860
1861#[cfg(not(feature = "simd"))]
1862#[inline(always)]
1863fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
1864 slice.iter().position(|t| *t == token.0 || *t == token.1)
1865}
1866
1867#[cfg(not(feature = "simd"))]
1868#[inline(always)]
1869fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
1870 slice
1871 .iter()
1872 .position(|t| *t == token.0 || *t == token.1 || *t == token.2)
1873}
1874
1875#[inline(always)]
1876fn memmem(slice: &[u8], literal: &[u8]) -> Option<core::ops::Range<usize>> {
1877 match literal.len() {
1878 0 => Some(0..0),
1879 1 => memchr(literal[0], slice).map(|i| i..i + 1),
1880 _ => memmem_(slice, literal),
1881 }
1882}
1883
1884#[inline(always)]
1885fn memmem2(slice: &[u8], literal: (&[u8], &[u8])) -> Option<core::ops::Range<usize>> {
1886 match (literal.0.len(), literal.1.len()) {
1887 (0, _) | (_, 0) => Some(0..0),
1888 (1, 1) => memchr2((literal.0[0], literal.1[0]), slice).map(|i| i..i + 1),
1889 _ => memmem2_(slice, literal),
1890 }
1891}
1892
1893#[inline(always)]
1894fn memmem3(slice: &[u8], literal: (&[u8], &[u8], &[u8])) -> Option<core::ops::Range<usize>> {
1895 match (literal.0.len(), literal.1.len(), literal.2.len()) {
1896 (0, _, _) | (_, 0, _) | (_, _, 0) => Some(0..0),
1897 (1, 1, 1) => memchr3((literal.0[0], literal.1[0], literal.2[0]), slice).map(|i| i..i + 1),
1898 _ => memmem3_(slice, literal),
1899 }
1900}
1901
1902#[cfg(feature = "simd")]
1903#[inline(always)]
1904fn memmem_(slice: &[u8], literal: &[u8]) -> Option<core::ops::Range<usize>> {
1905 let &prefix = match literal.first() {
1906 Some(x) => x,
1907 None => return Some(0..0),
1908 };
1909 #[allow(clippy::manual_find)] for i in memchr::memchr_iter(prefix, slice) {
1911 if slice[i..].starts_with(literal) {
1912 let i_end = i + literal.len();
1913 return Some(i..i_end);
1914 }
1915 }
1916 None
1917}
1918
1919#[cfg(feature = "simd")]
1920fn memmem2_(slice: &[u8], literal: (&[u8], &[u8])) -> Option<core::ops::Range<usize>> {
1921 let prefix = match (literal.0.first(), literal.1.first()) {
1922 (Some(&a), Some(&b)) => (a, b),
1923 _ => return Some(0..0),
1924 };
1925 #[allow(clippy::manual_find)] for i in memchr::memchr2_iter(prefix.0, prefix.1, slice) {
1927 let subslice = &slice[i..];
1928 if subslice.starts_with(literal.0) {
1929 let i_end = i + literal.0.len();
1930 return Some(i..i_end);
1931 }
1932 if subslice.starts_with(literal.1) {
1933 let i_end = i + literal.1.len();
1934 return Some(i..i_end);
1935 }
1936 }
1937 None
1938}
1939
1940#[cfg(feature = "simd")]
1941fn memmem3_(slice: &[u8], literal: (&[u8], &[u8], &[u8])) -> Option<core::ops::Range<usize>> {
1942 let prefix = match (literal.0.first(), literal.1.first(), literal.2.first()) {
1943 (Some(&a), Some(&b), Some(&c)) => (a, b, c),
1944 _ => return Some(0..0),
1945 };
1946 #[allow(clippy::manual_find)] for i in memchr::memchr3_iter(prefix.0, prefix.1, prefix.2, slice) {
1948 let subslice = &slice[i..];
1949 if subslice.starts_with(literal.0) {
1950 let i_end = i + literal.0.len();
1951 return Some(i..i_end);
1952 }
1953 if subslice.starts_with(literal.1) {
1954 let i_end = i + literal.1.len();
1955 return Some(i..i_end);
1956 }
1957 if subslice.starts_with(literal.2) {
1958 let i_end = i + literal.2.len();
1959 return Some(i..i_end);
1960 }
1961 }
1962 None
1963}
1964
1965#[cfg(not(feature = "simd"))]
1966fn memmem_(slice: &[u8], literal: &[u8]) -> Option<core::ops::Range<usize>> {
1967 for i in 0..slice.len() {
1968 let subslice = &slice[i..];
1969 if subslice.starts_with(literal) {
1970 let i_end = i + literal.len();
1971 return Some(i..i_end);
1972 }
1973 }
1974 None
1975}
1976
1977#[cfg(not(feature = "simd"))]
1978fn memmem2_(slice: &[u8], literal: (&[u8], &[u8])) -> Option<core::ops::Range<usize>> {
1979 for i in 0..slice.len() {
1980 let subslice = &slice[i..];
1981 if subslice.starts_with(literal.0) {
1982 let i_end = i + literal.0.len();
1983 return Some(i..i_end);
1984 }
1985 if subslice.starts_with(literal.1) {
1986 let i_end = i + literal.1.len();
1987 return Some(i..i_end);
1988 }
1989 }
1990 None
1991}
1992
1993#[cfg(not(feature = "simd"))]
1994fn memmem3_(slice: &[u8], literal: (&[u8], &[u8], &[u8])) -> Option<core::ops::Range<usize>> {
1995 for i in 0..slice.len() {
1996 let subslice = &slice[i..];
1997 if subslice.starts_with(literal.0) {
1998 let i_end = i + literal.0.len();
1999 return Some(i..i_end);
2000 }
2001 if subslice.starts_with(literal.1) {
2002 let i_end = i + literal.1.len();
2003 return Some(i..i_end);
2004 }
2005 if subslice.starts_with(literal.2) {
2006 let i_end = i + literal.2.len();
2007 return Some(i..i_end);
2008 }
2009 }
2010 None
2011}