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