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