1use core::hash::BuildHasher;
13use core::num::NonZeroUsize;
14
15use crate::ascii::Caseless as AsciiCaseless;
16use crate::error::Needed;
17use core::iter::{Cloned, Enumerate};
18use core::slice::Iter;
19use core::str::from_utf8;
20use core::str::CharIndices;
21use core::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 alloc::borrow::Cow;
29#[cfg(feature = "alloc")]
30use alloc::collections::BTreeMap;
31#[cfg(feature = "alloc")]
32use alloc::collections::BTreeSet;
33#[cfg(feature = "alloc")]
34use alloc::collections::VecDeque;
35#[cfg(feature = "alloc")]
36use alloc::string::String;
37#[cfg(feature = "alloc")]
38use alloc::vec::Vec;
39#[cfg(feature = "std")]
40use std::collections::HashMap;
41#[cfg(feature = "std")]
42use std::collections::HashSet;
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> + core::fmt::Debug {
139 type Token: core::fmt::Debug;
143 type Slice: core::fmt::Debug;
147
148 type IterOffsets: Iterator<Item = (usize, Self::Token)>;
150
151 type Checkpoint: Offset + Clone + core::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 core::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 + core::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 core::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 core::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 core::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) / core::mem::size_of::<T>()
841 }
842}
843
844impl<'a, T> Offset<<&'a [T] as Stream>::Checkpoint> for &'a [T]
845where
846 T: Clone + core::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<core::ops::Range<usize>>;
1092}
1093
1094impl<'s> FindSlice<&'s [u8]> for &[u8] {
1095 #[inline(always)]
1096 fn find_slice(&self, substr: &'s [u8]) -> Option<core::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<core::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(&self, substr: (&'s [u8], &'s [u8])) -> Option<core::ops::Range<usize>> {
1111 memmem2(self, substr)
1112 }
1113}
1114
1115impl<'s> FindSlice<(&'s [u8], &'s [u8], &'s [u8])> for &[u8] {
1116 #[inline(always)]
1117 fn find_slice(
1118 &self,
1119 substr: (&'s [u8], &'s [u8], &'s [u8]),
1120 ) -> Option<core::ops::Range<usize>> {
1121 memmem3(self, substr)
1122 }
1123}
1124
1125impl FindSlice<char> for &[u8] {
1126 #[inline(always)]
1127 fn find_slice(&self, substr: char) -> Option<core::ops::Range<usize>> {
1128 let mut b = [0; 4];
1129 let substr = substr.encode_utf8(&mut b);
1130 self.find_slice(&*substr)
1131 }
1132}
1133
1134impl FindSlice<(char,)> for &[u8] {
1135 #[inline(always)]
1136 fn find_slice(&self, substr: (char,)) -> Option<core::ops::Range<usize>> {
1137 let mut b = [0; 4];
1138 let substr0 = substr.0.encode_utf8(&mut b);
1139 self.find_slice((&*substr0,))
1140 }
1141}
1142
1143impl FindSlice<(char, char)> for &[u8] {
1144 #[inline(always)]
1145 fn find_slice(&self, substr: (char, char)) -> Option<core::ops::Range<usize>> {
1146 let mut b = [0; 4];
1147 let substr0 = substr.0.encode_utf8(&mut b);
1148 let mut b = [0; 4];
1149 let substr1 = substr.1.encode_utf8(&mut b);
1150 self.find_slice((&*substr0, &*substr1))
1151 }
1152}
1153
1154impl FindSlice<(char, char, char)> for &[u8] {
1155 #[inline(always)]
1156 fn find_slice(&self, substr: (char, char, char)) -> Option<core::ops::Range<usize>> {
1157 let mut b = [0; 4];
1158 let substr0 = substr.0.encode_utf8(&mut b);
1159 let mut b = [0; 4];
1160 let substr1 = substr.1.encode_utf8(&mut b);
1161 let mut b = [0; 4];
1162 let substr2 = substr.2.encode_utf8(&mut b);
1163 self.find_slice((&*substr0, &*substr1, &*substr2))
1164 }
1165}
1166
1167impl FindSlice<u8> for &[u8] {
1168 #[inline(always)]
1169 fn find_slice(&self, substr: u8) -> Option<core::ops::Range<usize>> {
1170 memchr(substr, self).map(|i| i..i + 1)
1171 }
1172}
1173
1174impl FindSlice<(u8,)> for &[u8] {
1175 #[inline(always)]
1176 fn find_slice(&self, substr: (u8,)) -> Option<core::ops::Range<usize>> {
1177 memchr(substr.0, self).map(|i| i..i + 1)
1178 }
1179}
1180
1181impl FindSlice<(u8, u8)> for &[u8] {
1182 #[inline(always)]
1183 fn find_slice(&self, substr: (u8, u8)) -> Option<core::ops::Range<usize>> {
1184 memchr2(substr, self).map(|i| i..i + 1)
1185 }
1186}
1187
1188impl FindSlice<(u8, u8, u8)> for &[u8] {
1189 #[inline(always)]
1190 fn find_slice(&self, substr: (u8, u8, u8)) -> Option<core::ops::Range<usize>> {
1191 memchr3(substr, self).map(|i| i..i + 1)
1192 }
1193}
1194
1195impl<'s> FindSlice<&'s str> for &[u8] {
1196 #[inline(always)]
1197 fn find_slice(&self, substr: &'s str) -> Option<core::ops::Range<usize>> {
1198 self.find_slice(substr.as_bytes())
1199 }
1200}
1201
1202impl<'s> FindSlice<(&'s str,)> for &[u8] {
1203 #[inline(always)]
1204 fn find_slice(&self, substr: (&'s str,)) -> Option<core::ops::Range<usize>> {
1205 memmem(self, substr.0.as_bytes())
1206 }
1207}
1208
1209impl<'s> FindSlice<(&'s str, &'s str)> for &[u8] {
1210 #[inline(always)]
1211 fn find_slice(&self, substr: (&'s str, &'s str)) -> Option<core::ops::Range<usize>> {
1212 memmem2(self, (substr.0.as_bytes(), substr.1.as_bytes()))
1213 }
1214}
1215
1216impl<'s> FindSlice<(&'s str, &'s str, &'s str)> for &[u8] {
1217 #[inline(always)]
1218 fn find_slice(&self, substr: (&'s str, &'s str, &'s str)) -> Option<core::ops::Range<usize>> {
1219 memmem3(
1220 self,
1221 (
1222 substr.0.as_bytes(),
1223 substr.1.as_bytes(),
1224 substr.2.as_bytes(),
1225 ),
1226 )
1227 }
1228}
1229
1230impl<'s> FindSlice<&'s str> for &str {
1231 #[inline(always)]
1232 fn find_slice(&self, substr: &'s str) -> Option<core::ops::Range<usize>> {
1233 self.as_bytes().find_slice(substr)
1234 }
1235}
1236
1237impl<'s> FindSlice<(&'s str,)> for &str {
1238 #[inline(always)]
1239 fn find_slice(&self, substr: (&'s str,)) -> Option<core::ops::Range<usize>> {
1240 self.as_bytes().find_slice(substr)
1241 }
1242}
1243
1244impl<'s> FindSlice<(&'s str, &'s str)> for &str {
1245 #[inline(always)]
1246 fn find_slice(&self, substr: (&'s str, &'s str)) -> Option<core::ops::Range<usize>> {
1247 self.as_bytes().find_slice(substr)
1248 }
1249}
1250
1251impl<'s> FindSlice<(&'s str, &'s str, &'s str)> for &str {
1252 #[inline(always)]
1253 fn find_slice(&self, substr: (&'s str, &'s str, &'s str)) -> Option<core::ops::Range<usize>> {
1254 self.as_bytes().find_slice(substr)
1255 }
1256}
1257
1258impl FindSlice<char> for &str {
1259 #[inline(always)]
1260 fn find_slice(&self, substr: char) -> Option<core::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<core::ops::Range<usize>> {
1268 self.as_bytes().find_slice(substr)
1269 }
1270}
1271
1272impl FindSlice<(char, char)> for &str {
1273 #[inline(always)]
1274 fn find_slice(&self, substr: (char, char)) -> Option<core::ops::Range<usize>> {
1275 self.as_bytes().find_slice(substr)
1276 }
1277}
1278
1279impl FindSlice<(char, char, char)> for &str {
1280 #[inline(always)]
1281 fn find_slice(&self, substr: (char, char, char)) -> Option<core::ops::Range<usize>> {
1282 self.as_bytes().find_slice(substr)
1283 }
1284}
1285
1286pub trait ParseSlice<R> {
1288 fn parse_slice(&self) -> Option<R>;
1293}
1294
1295impl<R: FromStr> ParseSlice<R> for &[u8] {
1296 #[inline(always)]
1297 fn parse_slice(&self) -> Option<R> {
1298 from_utf8(self).ok().and_then(|s| s.parse().ok())
1299 }
1300}
1301
1302impl<R: FromStr> ParseSlice<R> for &str {
1303 #[inline(always)]
1304 fn parse_slice(&self) -> Option<R> {
1305 self.parse().ok()
1306 }
1307}
1308
1309pub trait UpdateSlice: Stream {
1311 fn update_slice(self, inner: Self::Slice) -> Self;
1313}
1314
1315impl<T> UpdateSlice for &[T]
1316where
1317 T: Clone + core::fmt::Debug,
1318{
1319 #[inline(always)]
1320 fn update_slice(self, inner: Self::Slice) -> Self {
1321 inner
1322 }
1323}
1324
1325impl UpdateSlice for &str {
1326 #[inline(always)]
1327 fn update_slice(self, inner: Self::Slice) -> Self {
1328 inner
1329 }
1330}
1331
1332pub struct Checkpoint<T, S> {
1334 inner: T,
1335 stream: core::marker::PhantomData<S>,
1336}
1337
1338impl<T, S> Checkpoint<T, S> {
1339 fn new(inner: T) -> Self {
1340 Self {
1341 inner,
1342 stream: Default::default(),
1343 }
1344 }
1345}
1346
1347impl<T: Copy, S> Copy for Checkpoint<T, S> {}
1348
1349impl<T: Clone, S> Clone for Checkpoint<T, S> {
1350 #[inline(always)]
1351 fn clone(&self) -> Self {
1352 Self {
1353 inner: self.inner.clone(),
1354 stream: Default::default(),
1355 }
1356 }
1357}
1358
1359impl<T: PartialOrd, S> PartialOrd for Checkpoint<T, S> {
1360 #[inline(always)]
1361 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1362 self.inner.partial_cmp(&other.inner)
1363 }
1364}
1365
1366impl<T: Ord, S> Ord for Checkpoint<T, S> {
1367 #[inline(always)]
1368 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1369 self.inner.cmp(&other.inner)
1370 }
1371}
1372
1373impl<T: PartialEq, S> PartialEq for Checkpoint<T, S> {
1374 #[inline(always)]
1375 fn eq(&self, other: &Self) -> bool {
1376 self.inner.eq(&other.inner)
1377 }
1378}
1379
1380impl<T: Eq, S> Eq for Checkpoint<T, S> {}
1381
1382impl<T: core::fmt::Debug, S> core::fmt::Debug for Checkpoint<T, S> {
1383 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1384 self.inner.fmt(f)
1385 }
1386}
1387
1388pub trait Accumulate<T>: Sized {
1392 fn initial(capacity: Option<usize>) -> Self;
1394 fn accumulate(&mut self, acc: T);
1396}
1397
1398impl<T> Accumulate<T> for () {
1399 #[inline(always)]
1400 fn initial(_capacity: Option<usize>) -> Self {}
1401 #[inline(always)]
1402 fn accumulate(&mut self, _acc: T) {}
1403}
1404
1405impl<T> Accumulate<T> for usize {
1406 #[inline(always)]
1407 fn initial(_capacity: Option<usize>) -> Self {
1408 0
1409 }
1410 #[inline(always)]
1411 fn accumulate(&mut self, _acc: T) {
1412 *self += 1;
1413 }
1414}
1415
1416#[cfg(feature = "alloc")]
1417impl<T> Accumulate<T> for Vec<T> {
1418 #[inline(always)]
1419 fn initial(capacity: Option<usize>) -> Self {
1420 match capacity {
1421 Some(capacity) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
1422 None => Vec::new(),
1423 }
1424 }
1425 #[inline(always)]
1426 fn accumulate(&mut self, acc: T) {
1427 self.push(acc);
1428 }
1429}
1430
1431#[cfg(feature = "alloc")]
1432impl<'i, T: Clone> Accumulate<&'i [T]> for Vec<T> {
1433 #[inline(always)]
1434 fn initial(capacity: Option<usize>) -> Self {
1435 match capacity {
1436 Some(capacity) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
1437 None => Vec::new(),
1438 }
1439 }
1440 #[inline(always)]
1441 fn accumulate(&mut self, acc: &'i [T]) {
1442 self.extend(acc.iter().cloned());
1443 }
1444}
1445
1446#[cfg(feature = "alloc")]
1447impl Accumulate<char> for String {
1448 #[inline(always)]
1449 fn initial(capacity: Option<usize>) -> Self {
1450 match capacity {
1451 Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1452 None => String::new(),
1453 }
1454 }
1455 #[inline(always)]
1456 fn accumulate(&mut self, acc: char) {
1457 self.push(acc);
1458 }
1459}
1460
1461#[cfg(feature = "alloc")]
1462impl<'i> Accumulate<&'i str> for String {
1463 #[inline(always)]
1464 fn initial(capacity: Option<usize>) -> Self {
1465 match capacity {
1466 Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1467 None => String::new(),
1468 }
1469 }
1470 #[inline(always)]
1471 fn accumulate(&mut self, acc: &'i str) {
1472 self.push_str(acc);
1473 }
1474}
1475
1476#[cfg(feature = "alloc")]
1477impl<'i> Accumulate<Cow<'i, str>> for String {
1478 #[inline(always)]
1479 fn initial(capacity: Option<usize>) -> Self {
1480 match capacity {
1481 Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1482 None => String::new(),
1483 }
1484 }
1485 #[inline(always)]
1486 fn accumulate(&mut self, acc: Cow<'i, str>) {
1487 self.push_str(&acc);
1488 }
1489}
1490
1491#[cfg(feature = "alloc")]
1492impl Accumulate<String> for String {
1493 #[inline(always)]
1494 fn initial(capacity: Option<usize>) -> Self {
1495 match capacity {
1496 Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1497 None => String::new(),
1498 }
1499 }
1500 #[inline(always)]
1501 fn accumulate(&mut self, acc: String) {
1502 self.push_str(&acc);
1503 }
1504}
1505
1506#[cfg(feature = "alloc")]
1507impl<K, V> Accumulate<(K, V)> for BTreeMap<K, V>
1508where
1509 K: core::cmp::Ord,
1510{
1511 #[inline(always)]
1512 fn initial(_capacity: Option<usize>) -> Self {
1513 BTreeMap::new()
1514 }
1515 #[inline(always)]
1516 fn accumulate(&mut self, (key, value): (K, V)) {
1517 self.insert(key, value);
1518 }
1519}
1520
1521#[cfg(feature = "std")]
1522impl<K, V, S> Accumulate<(K, V)> for HashMap<K, V, S>
1523where
1524 K: core::cmp::Eq + core::hash::Hash,
1525 S: BuildHasher + Default,
1526{
1527 #[inline(always)]
1528 fn initial(capacity: Option<usize>) -> Self {
1529 let h = S::default();
1530 match capacity {
1531 Some(capacity) => {
1532 HashMap::with_capacity_and_hasher(clamp_capacity::<(K, V)>(capacity), h)
1533 }
1534 None => HashMap::with_hasher(h),
1535 }
1536 }
1537 #[inline(always)]
1538 fn accumulate(&mut self, (key, value): (K, V)) {
1539 self.insert(key, value);
1540 }
1541}
1542
1543#[cfg(feature = "alloc")]
1544impl<K> Accumulate<K> for BTreeSet<K>
1545where
1546 K: core::cmp::Ord,
1547{
1548 #[inline(always)]
1549 fn initial(_capacity: Option<usize>) -> Self {
1550 BTreeSet::new()
1551 }
1552 #[inline(always)]
1553 fn accumulate(&mut self, key: K) {
1554 self.insert(key);
1555 }
1556}
1557
1558#[cfg(feature = "std")]
1559impl<K, S> Accumulate<K> for HashSet<K, S>
1560where
1561 K: core::cmp::Eq + core::hash::Hash,
1562 S: BuildHasher + Default,
1563{
1564 #[inline(always)]
1565 fn initial(capacity: Option<usize>) -> Self {
1566 let h = S::default();
1567 match capacity {
1568 Some(capacity) => HashSet::with_capacity_and_hasher(clamp_capacity::<K>(capacity), h),
1569 None => HashSet::with_hasher(h),
1570 }
1571 }
1572 #[inline(always)]
1573 fn accumulate(&mut self, key: K) {
1574 self.insert(key);
1575 }
1576}
1577
1578#[cfg(feature = "alloc")]
1579impl<'i, T: Clone> Accumulate<&'i [T]> for VecDeque<T> {
1580 #[inline(always)]
1581 fn initial(capacity: Option<usize>) -> Self {
1582 match capacity {
1583 Some(capacity) => VecDeque::with_capacity(clamp_capacity::<T>(capacity)),
1584 None => VecDeque::new(),
1585 }
1586 }
1587 #[inline(always)]
1588 fn accumulate(&mut self, acc: &'i [T]) {
1589 self.extend(acc.iter().cloned());
1590 }
1591}
1592
1593#[cfg(feature = "alloc")]
1594#[inline]
1595pub(crate) fn clamp_capacity<T>(capacity: usize) -> usize {
1596 const MAX_INITIAL_CAPACITY_BYTES: usize = 65536;
1606
1607 let max_initial_capacity = MAX_INITIAL_CAPACITY_BYTES / core::mem::size_of::<T>().max(1);
1608 capacity.min(max_initial_capacity)
1609}
1610
1611pub trait ToUsize {
1618 fn to_usize(&self) -> usize;
1620}
1621
1622impl ToUsize for u8 {
1623 #[inline(always)]
1624 fn to_usize(&self) -> usize {
1625 *self as usize
1626 }
1627}
1628
1629impl ToUsize for u16 {
1630 #[inline(always)]
1631 fn to_usize(&self) -> usize {
1632 *self as usize
1633 }
1634}
1635
1636impl ToUsize for usize {
1637 #[inline(always)]
1638 fn to_usize(&self) -> usize {
1639 *self
1640 }
1641}
1642
1643#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
1644impl ToUsize for u32 {
1645 #[inline(always)]
1646 fn to_usize(&self) -> usize {
1647 *self as usize
1648 }
1649}
1650
1651#[cfg(target_pointer_width = "64")]
1652impl ToUsize for u64 {
1653 #[inline(always)]
1654 fn to_usize(&self) -> usize {
1655 *self as usize
1656 }
1657}
1658
1659#[allow(clippy::len_without_is_empty)]
1661#[allow(clippy::wrong_self_convention)]
1662pub trait AsChar {
1663 fn as_char(self) -> char;
1674
1675 fn is_alpha(self) -> bool;
1684
1685 fn is_alphanum(self) -> bool;
1688 fn is_dec_digit(self) -> bool;
1690 fn is_hex_digit(self) -> bool;
1692 fn is_oct_digit(self) -> bool;
1694 fn len(self) -> usize;
1696 fn is_space(self) -> bool;
1698 fn is_newline(self) -> bool;
1700}
1701
1702impl AsChar for u8 {
1703 #[inline(always)]
1704 fn as_char(self) -> char {
1705 self as char
1706 }
1707 #[inline]
1708 fn is_alpha(self) -> bool {
1709 matches!(self, 0x41..=0x5A | 0x61..=0x7A)
1710 }
1711 #[inline]
1712 fn is_alphanum(self) -> bool {
1713 self.is_alpha() || self.is_dec_digit()
1714 }
1715 #[inline]
1716 fn is_dec_digit(self) -> bool {
1717 matches!(self, 0x30..=0x39)
1718 }
1719 #[inline]
1720 fn is_hex_digit(self) -> bool {
1721 matches!(self, 0x30..=0x39 | 0x41..=0x46 | 0x61..=0x66)
1722 }
1723 #[inline]
1724 fn is_oct_digit(self) -> bool {
1725 matches!(self, 0x30..=0x37)
1726 }
1727 #[inline]
1728 fn len(self) -> usize {
1729 1
1730 }
1731 #[inline]
1732 fn is_space(self) -> bool {
1733 self == b' ' || self == b'\t'
1734 }
1735 #[inline]
1736 fn is_newline(self) -> bool {
1737 self == b'\n'
1738 }
1739}
1740
1741impl AsChar for &u8 {
1742 #[inline(always)]
1743 fn as_char(self) -> char {
1744 (*self).as_char()
1745 }
1746 #[inline(always)]
1747 fn is_alpha(self) -> bool {
1748 (*self).is_alpha()
1749 }
1750 #[inline(always)]
1751 fn is_alphanum(self) -> bool {
1752 (*self).is_alphanum()
1753 }
1754 #[inline(always)]
1755 fn is_dec_digit(self) -> bool {
1756 (*self).is_dec_digit()
1757 }
1758 #[inline(always)]
1759 fn is_hex_digit(self) -> bool {
1760 (*self).is_hex_digit()
1761 }
1762 #[inline(always)]
1763 fn is_oct_digit(self) -> bool {
1764 (*self).is_oct_digit()
1765 }
1766 #[inline(always)]
1767 fn len(self) -> usize {
1768 (*self).len()
1769 }
1770 #[inline(always)]
1771 fn is_space(self) -> bool {
1772 (*self).is_space()
1773 }
1774 #[inline(always)]
1775 fn is_newline(self) -> bool {
1776 (*self).is_newline()
1777 }
1778}
1779
1780impl AsChar for char {
1781 #[inline(always)]
1782 fn as_char(self) -> char {
1783 self
1784 }
1785 #[inline]
1786 fn is_alpha(self) -> bool {
1787 self.is_ascii_alphabetic()
1788 }
1789 #[inline]
1790 fn is_alphanum(self) -> bool {
1791 self.is_alpha() || self.is_dec_digit()
1792 }
1793 #[inline]
1794 fn is_dec_digit(self) -> bool {
1795 self.is_ascii_digit()
1796 }
1797 #[inline]
1798 fn is_hex_digit(self) -> bool {
1799 self.is_ascii_hexdigit()
1800 }
1801 #[inline]
1802 fn is_oct_digit(self) -> bool {
1803 self.is_digit(8)
1804 }
1805 #[inline]
1806 fn len(self) -> usize {
1807 self.len_utf8()
1808 }
1809 #[inline]
1810 fn is_space(self) -> bool {
1811 self == ' ' || self == '\t'
1812 }
1813 #[inline]
1814 fn is_newline(self) -> bool {
1815 self == '\n'
1816 }
1817}
1818
1819impl AsChar for &char {
1820 #[inline(always)]
1821 fn as_char(self) -> char {
1822 (*self).as_char()
1823 }
1824 #[inline(always)]
1825 fn is_alpha(self) -> bool {
1826 (*self).is_alpha()
1827 }
1828 #[inline(always)]
1829 fn is_alphanum(self) -> bool {
1830 (*self).is_alphanum()
1831 }
1832 #[inline(always)]
1833 fn is_dec_digit(self) -> bool {
1834 (*self).is_dec_digit()
1835 }
1836 #[inline(always)]
1837 fn is_hex_digit(self) -> bool {
1838 (*self).is_hex_digit()
1839 }
1840 #[inline(always)]
1841 fn is_oct_digit(self) -> bool {
1842 (*self).is_oct_digit()
1843 }
1844 #[inline(always)]
1845 fn len(self) -> usize {
1846 (*self).len()
1847 }
1848 #[inline(always)]
1849 fn is_space(self) -> bool {
1850 (*self).is_space()
1851 }
1852 #[inline(always)]
1853 fn is_newline(self) -> bool {
1854 (*self).is_newline()
1855 }
1856}
1857
1858pub trait ContainsToken<T> {
1883 fn contains_token(&self, token: T) -> bool;
1885}
1886
1887impl ContainsToken<u8> for u8 {
1888 #[inline(always)]
1889 fn contains_token(&self, token: u8) -> bool {
1890 *self == token
1891 }
1892}
1893
1894impl ContainsToken<&u8> for u8 {
1895 #[inline(always)]
1896 fn contains_token(&self, token: &u8) -> bool {
1897 self.contains_token(*token)
1898 }
1899}
1900
1901impl ContainsToken<char> for u8 {
1902 #[inline(always)]
1903 fn contains_token(&self, token: char) -> bool {
1904 self.as_char() == token
1905 }
1906}
1907
1908impl ContainsToken<&char> for u8 {
1909 #[inline(always)]
1910 fn contains_token(&self, token: &char) -> bool {
1911 self.contains_token(*token)
1912 }
1913}
1914
1915impl<C: AsChar> ContainsToken<C> for char {
1916 #[inline(always)]
1917 fn contains_token(&self, token: C) -> bool {
1918 *self == token.as_char()
1919 }
1920}
1921
1922impl<C, F: Fn(C) -> bool> ContainsToken<C> for F {
1923 #[inline(always)]
1924 fn contains_token(&self, token: C) -> bool {
1925 self(token)
1926 }
1927}
1928
1929impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::Range<C2> {
1930 #[inline(always)]
1931 fn contains_token(&self, token: C1) -> bool {
1932 let start = self.start.clone().as_char();
1933 let end = self.end.clone().as_char();
1934 (start..end).contains(&token.as_char())
1935 }
1936}
1937
1938impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeInclusive<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> for core::ops::RangeFrom<C2> {
1948 #[inline(always)]
1949 fn contains_token(&self, token: C1) -> bool {
1950 let start = self.start.clone().as_char();
1951 (start..).contains(&token.as_char())
1952 }
1953}
1954
1955impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeTo<C2> {
1956 #[inline(always)]
1957 fn contains_token(&self, token: C1) -> bool {
1958 let end = self.end.clone().as_char();
1959 (..end).contains(&token.as_char())
1960 }
1961}
1962
1963impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeToInclusive<C2> {
1964 #[inline(always)]
1965 fn contains_token(&self, token: C1) -> bool {
1966 let end = self.end.clone().as_char();
1967 (..=end).contains(&token.as_char())
1968 }
1969}
1970
1971impl<C1: AsChar> ContainsToken<C1> for core::ops::RangeFull {
1972 #[inline(always)]
1973 fn contains_token(&self, _token: C1) -> bool {
1974 true
1975 }
1976}
1977
1978impl<C: AsChar> ContainsToken<C> for &'_ [u8] {
1979 #[inline]
1980 fn contains_token(&self, token: C) -> bool {
1981 let token = token.as_char();
1982 self.iter().any(|t| t.as_char() == token)
1983 }
1984}
1985
1986impl<C: AsChar> ContainsToken<C> for &'_ [char] {
1987 #[inline]
1988 fn contains_token(&self, token: C) -> bool {
1989 let token = token.as_char();
1990 self.contains(&token)
1991 }
1992}
1993
1994impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [u8; LEN] {
1995 #[inline]
1996 fn contains_token(&self, token: C) -> bool {
1997 let token = token.as_char();
1998 self.iter().any(|t| t.as_char() == token)
1999 }
2000}
2001
2002impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [char; LEN] {
2003 #[inline]
2004 fn contains_token(&self, token: C) -> bool {
2005 let token = token.as_char();
2006 self.contains(&token)
2007 }
2008}
2009
2010impl<const LEN: usize, C: AsChar> ContainsToken<C> for [u8; LEN] {
2011 #[inline]
2012 fn contains_token(&self, token: C) -> bool {
2013 let token = token.as_char();
2014 self.iter().any(|t| t.as_char() == token)
2015 }
2016}
2017
2018impl<const LEN: usize, C: AsChar> ContainsToken<C> for [char; LEN] {
2019 #[inline]
2020 fn contains_token(&self, token: C) -> bool {
2021 let token = token.as_char();
2022 self.contains(&token)
2023 }
2024}
2025
2026impl<T> ContainsToken<T> for () {
2027 #[inline(always)]
2028 fn contains_token(&self, _token: T) -> bool {
2029 false
2030 }
2031}
2032
2033macro_rules! impl_contains_token_for_tuple {
2034 ($($haystack:ident),+) => (
2035 #[allow(non_snake_case)]
2036 impl<T, $($haystack),+> ContainsToken<T> for ($($haystack),+,)
2037 where
2038 T: Clone,
2039 $($haystack: ContainsToken<T>),+
2040 {
2041 #[inline]
2042 fn contains_token(&self, token: T) -> bool {
2043 let ($(ref $haystack),+,) = *self;
2044 $($haystack.contains_token(token.clone()) || )+ false
2045 }
2046 }
2047 )
2048}
2049
2050macro_rules! impl_contains_token_for_tuples {
2051 ($haystack1:ident, $($haystack:ident),+) => {
2052 impl_contains_token_for_tuples!(__impl $haystack1; $($haystack),+);
2053 };
2054 (__impl $($haystack:ident),+; $haystack1:ident $(,$haystack2:ident)*) => {
2055 impl_contains_token_for_tuple!($($haystack),+);
2056 impl_contains_token_for_tuples!(__impl $($haystack),+, $haystack1; $($haystack2),*);
2057 };
2058 (__impl $($haystack:ident),+;) => {
2059 impl_contains_token_for_tuple!($($haystack),+);
2060 }
2061}
2062
2063impl_contains_token_for_tuples!(
2064 F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21
2065);
2066
2067#[cfg(feature = "simd")]
2068#[inline(always)]
2069fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
2070 memchr::memchr(token, slice)
2071}
2072
2073#[cfg(feature = "simd")]
2074#[inline(always)]
2075fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
2076 memchr::memchr2(token.0, token.1, slice)
2077}
2078
2079#[cfg(feature = "simd")]
2080#[inline(always)]
2081fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
2082 memchr::memchr3(token.0, token.1, token.2, slice)
2083}
2084
2085#[cfg(not(feature = "simd"))]
2086#[inline(always)]
2087fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
2088 slice.iter().position(|t| *t == token)
2089}
2090
2091#[cfg(not(feature = "simd"))]
2092#[inline(always)]
2093fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
2094 slice.iter().position(|t| *t == token.0 || *t == token.1)
2095}
2096
2097#[cfg(not(feature = "simd"))]
2098#[inline(always)]
2099fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
2100 slice
2101 .iter()
2102 .position(|t| *t == token.0 || *t == token.1 || *t == token.2)
2103}
2104
2105#[inline(always)]
2106fn memmem(slice: &[u8], literal: &[u8]) -> Option<core::ops::Range<usize>> {
2107 match literal.len() {
2108 0 => Some(0..0),
2109 1 => memchr(literal[0], slice).map(|i| i..i + 1),
2110 _ => memmem_(slice, literal),
2111 }
2112}
2113
2114#[inline(always)]
2115fn memmem2(slice: &[u8], literal: (&[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2116 match (literal.0.len(), literal.1.len()) {
2117 (0, _) | (_, 0) => Some(0..0),
2118 (1, 1) => memchr2((literal.0[0], literal.1[0]), slice).map(|i| i..i + 1),
2119 _ => memmem2_(slice, literal),
2120 }
2121}
2122
2123#[inline(always)]
2124fn memmem3(slice: &[u8], literal: (&[u8], &[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2125 match (literal.0.len(), literal.1.len(), literal.2.len()) {
2126 (0, _, _) | (_, 0, _) | (_, _, 0) => Some(0..0),
2127 (1, 1, 1) => memchr3((literal.0[0], literal.1[0], literal.2[0]), slice).map(|i| i..i + 1),
2128 _ => memmem3_(slice, literal),
2129 }
2130}
2131
2132#[cfg(feature = "simd")]
2133#[inline(always)]
2134fn memmem_(slice: &[u8], literal: &[u8]) -> Option<core::ops::Range<usize>> {
2135 let &prefix = match literal.first() {
2136 Some(x) => x,
2137 None => return Some(0..0),
2138 };
2139 #[allow(clippy::manual_find)] for i in memchr::memchr_iter(prefix, slice) {
2141 if slice[i..].starts_with(literal) {
2142 let i_end = i + literal.len();
2143 return Some(i..i_end);
2144 }
2145 }
2146 None
2147}
2148
2149#[cfg(feature = "simd")]
2150fn memmem2_(slice: &[u8], literal: (&[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2151 let prefix = match (literal.0.first(), literal.1.first()) {
2152 (Some(&a), Some(&b)) => (a, b),
2153 _ => return Some(0..0),
2154 };
2155 #[allow(clippy::manual_find)] for i in memchr::memchr2_iter(prefix.0, prefix.1, slice) {
2157 let subslice = &slice[i..];
2158 if subslice.starts_with(literal.0) {
2159 let i_end = i + literal.0.len();
2160 return Some(i..i_end);
2161 }
2162 if subslice.starts_with(literal.1) {
2163 let i_end = i + literal.1.len();
2164 return Some(i..i_end);
2165 }
2166 }
2167 None
2168}
2169
2170#[cfg(feature = "simd")]
2171fn memmem3_(slice: &[u8], literal: (&[u8], &[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2172 let prefix = match (literal.0.first(), literal.1.first(), literal.2.first()) {
2173 (Some(&a), Some(&b), Some(&c)) => (a, b, c),
2174 _ => return Some(0..0),
2175 };
2176 #[allow(clippy::manual_find)] for i in memchr::memchr3_iter(prefix.0, prefix.1, prefix.2, slice) {
2178 let subslice = &slice[i..];
2179 if subslice.starts_with(literal.0) {
2180 let i_end = i + literal.0.len();
2181 return Some(i..i_end);
2182 }
2183 if subslice.starts_with(literal.1) {
2184 let i_end = i + literal.1.len();
2185 return Some(i..i_end);
2186 }
2187 if subslice.starts_with(literal.2) {
2188 let i_end = i + literal.2.len();
2189 return Some(i..i_end);
2190 }
2191 }
2192 None
2193}
2194
2195#[cfg(not(feature = "simd"))]
2196fn memmem_(slice: &[u8], literal: &[u8]) -> Option<core::ops::Range<usize>> {
2197 for i in 0..slice.len() {
2198 let subslice = &slice[i..];
2199 if subslice.starts_with(literal) {
2200 let i_end = i + literal.len();
2201 return Some(i..i_end);
2202 }
2203 }
2204 None
2205}
2206
2207#[cfg(not(feature = "simd"))]
2208fn memmem2_(slice: &[u8], literal: (&[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2209 for i in 0..slice.len() {
2210 let subslice = &slice[i..];
2211 if subslice.starts_with(literal.0) {
2212 let i_end = i + literal.0.len();
2213 return Some(i..i_end);
2214 }
2215 if subslice.starts_with(literal.1) {
2216 let i_end = i + literal.1.len();
2217 return Some(i..i_end);
2218 }
2219 }
2220 None
2221}
2222
2223#[cfg(not(feature = "simd"))]
2224fn memmem3_(slice: &[u8], literal: (&[u8], &[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2225 for i in 0..slice.len() {
2226 let subslice = &slice[i..];
2227 if subslice.starts_with(literal.0) {
2228 let i_end = i + literal.0.len();
2229 return Some(i..i_end);
2230 }
2231 if subslice.starts_with(literal.1) {
2232 let i_end = i + literal.1.len();
2233 return Some(i..i_end);
2234 }
2235 if subslice.starts_with(literal.2) {
2236 let i_end = i + literal.2.len();
2237 return Some(i..i_end);
2238 }
2239 }
2240 None
2241}