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