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 {
1391 fn initial(capacity: Option<usize>) -> Self;
1393 fn accumulate(&mut self, acc: T);
1395}
1396
1397impl<T> Accumulate<T> for () {
1398 #[inline(always)]
1399 fn initial(_capacity: Option<usize>) -> Self {}
1400 #[inline(always)]
1401 fn accumulate(&mut self, _acc: T) {}
1402}
1403
1404impl<T> Accumulate<T> for usize {
1405 #[inline(always)]
1406 fn initial(_capacity: Option<usize>) -> Self {
1407 0
1408 }
1409 #[inline(always)]
1410 fn accumulate(&mut self, _acc: T) {
1411 *self += 1;
1412 }
1413}
1414
1415#[cfg(feature = "alloc")]
1416impl<T> Accumulate<T> for Vec<T> {
1417 #[inline(always)]
1418 fn initial(capacity: Option<usize>) -> Self {
1419 match capacity {
1420 Some(capacity) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
1421 None => Vec::new(),
1422 }
1423 }
1424 #[inline(always)]
1425 fn accumulate(&mut self, acc: T) {
1426 self.push(acc);
1427 }
1428}
1429
1430#[cfg(feature = "alloc")]
1431impl<'i, T: Clone> Accumulate<&'i [T]> for Vec<T> {
1432 #[inline(always)]
1433 fn initial(capacity: Option<usize>) -> Self {
1434 match capacity {
1435 Some(capacity) => Vec::with_capacity(clamp_capacity::<T>(capacity)),
1436 None => Vec::new(),
1437 }
1438 }
1439 #[inline(always)]
1440 fn accumulate(&mut self, acc: &'i [T]) {
1441 self.extend(acc.iter().cloned());
1442 }
1443}
1444
1445#[cfg(feature = "alloc")]
1446impl Accumulate<char> for String {
1447 #[inline(always)]
1448 fn initial(capacity: Option<usize>) -> Self {
1449 match capacity {
1450 Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1451 None => String::new(),
1452 }
1453 }
1454 #[inline(always)]
1455 fn accumulate(&mut self, acc: char) {
1456 self.push(acc);
1457 }
1458}
1459
1460#[cfg(feature = "alloc")]
1461impl<'i> Accumulate<&'i str> for String {
1462 #[inline(always)]
1463 fn initial(capacity: Option<usize>) -> Self {
1464 match capacity {
1465 Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1466 None => String::new(),
1467 }
1468 }
1469 #[inline(always)]
1470 fn accumulate(&mut self, acc: &'i str) {
1471 self.push_str(acc);
1472 }
1473}
1474
1475#[cfg(feature = "alloc")]
1476impl<'i> Accumulate<Cow<'i, str>> for String {
1477 #[inline(always)]
1478 fn initial(capacity: Option<usize>) -> Self {
1479 match capacity {
1480 Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1481 None => String::new(),
1482 }
1483 }
1484 #[inline(always)]
1485 fn accumulate(&mut self, acc: Cow<'i, str>) {
1486 self.push_str(&acc);
1487 }
1488}
1489
1490#[cfg(feature = "alloc")]
1491impl Accumulate<String> for String {
1492 #[inline(always)]
1493 fn initial(capacity: Option<usize>) -> Self {
1494 match capacity {
1495 Some(capacity) => String::with_capacity(clamp_capacity::<char>(capacity)),
1496 None => String::new(),
1497 }
1498 }
1499 #[inline(always)]
1500 fn accumulate(&mut self, acc: String) {
1501 self.push_str(&acc);
1502 }
1503}
1504
1505#[cfg(feature = "alloc")]
1506impl<K, V> Accumulate<(K, V)> for BTreeMap<K, V>
1507where
1508 K: core::cmp::Ord,
1509{
1510 #[inline(always)]
1511 fn initial(_capacity: Option<usize>) -> Self {
1512 BTreeMap::new()
1513 }
1514 #[inline(always)]
1515 fn accumulate(&mut self, (key, value): (K, V)) {
1516 self.insert(key, value);
1517 }
1518}
1519
1520#[cfg(feature = "std")]
1521impl<K, V, S> Accumulate<(K, V)> for HashMap<K, V, S>
1522where
1523 K: core::cmp::Eq + core::hash::Hash,
1524 S: BuildHasher + Default,
1525{
1526 #[inline(always)]
1527 fn initial(capacity: Option<usize>) -> Self {
1528 let h = S::default();
1529 match capacity {
1530 Some(capacity) => {
1531 HashMap::with_capacity_and_hasher(clamp_capacity::<(K, V)>(capacity), h)
1532 }
1533 None => HashMap::with_hasher(h),
1534 }
1535 }
1536 #[inline(always)]
1537 fn accumulate(&mut self, (key, value): (K, V)) {
1538 self.insert(key, value);
1539 }
1540}
1541
1542#[cfg(feature = "alloc")]
1543impl<K> Accumulate<K> for BTreeSet<K>
1544where
1545 K: core::cmp::Ord,
1546{
1547 #[inline(always)]
1548 fn initial(_capacity: Option<usize>) -> Self {
1549 BTreeSet::new()
1550 }
1551 #[inline(always)]
1552 fn accumulate(&mut self, key: K) {
1553 self.insert(key);
1554 }
1555}
1556
1557#[cfg(feature = "std")]
1558impl<K, S> Accumulate<K> for HashSet<K, S>
1559where
1560 K: core::cmp::Eq + core::hash::Hash,
1561 S: BuildHasher + Default,
1562{
1563 #[inline(always)]
1564 fn initial(capacity: Option<usize>) -> Self {
1565 let h = S::default();
1566 match capacity {
1567 Some(capacity) => HashSet::with_capacity_and_hasher(clamp_capacity::<K>(capacity), h),
1568 None => HashSet::with_hasher(h),
1569 }
1570 }
1571 #[inline(always)]
1572 fn accumulate(&mut self, key: K) {
1573 self.insert(key);
1574 }
1575}
1576
1577#[cfg(feature = "alloc")]
1578impl<'i, T: Clone> Accumulate<&'i [T]> for VecDeque<T> {
1579 #[inline(always)]
1580 fn initial(capacity: Option<usize>) -> Self {
1581 match capacity {
1582 Some(capacity) => VecDeque::with_capacity(clamp_capacity::<T>(capacity)),
1583 None => VecDeque::new(),
1584 }
1585 }
1586 #[inline(always)]
1587 fn accumulate(&mut self, acc: &'i [T]) {
1588 self.extend(acc.iter().cloned());
1589 }
1590}
1591
1592#[cfg(feature = "alloc")]
1593#[inline]
1594pub(crate) fn clamp_capacity<T>(capacity: usize) -> usize {
1595 const MAX_INITIAL_CAPACITY_BYTES: usize = 65536;
1605
1606 let max_initial_capacity = MAX_INITIAL_CAPACITY_BYTES / core::mem::size_of::<T>().max(1);
1607 capacity.min(max_initial_capacity)
1608}
1609
1610pub trait ToUsize {
1617 fn to_usize(&self) -> usize;
1619}
1620
1621impl ToUsize for u8 {
1622 #[inline(always)]
1623 fn to_usize(&self) -> usize {
1624 *self as usize
1625 }
1626}
1627
1628impl ToUsize for u16 {
1629 #[inline(always)]
1630 fn to_usize(&self) -> usize {
1631 *self as usize
1632 }
1633}
1634
1635impl ToUsize for usize {
1636 #[inline(always)]
1637 fn to_usize(&self) -> usize {
1638 *self
1639 }
1640}
1641
1642#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
1643impl ToUsize for u32 {
1644 #[inline(always)]
1645 fn to_usize(&self) -> usize {
1646 *self as usize
1647 }
1648}
1649
1650#[cfg(target_pointer_width = "64")]
1651impl ToUsize for u64 {
1652 #[inline(always)]
1653 fn to_usize(&self) -> usize {
1654 *self as usize
1655 }
1656}
1657
1658#[allow(clippy::len_without_is_empty)]
1660#[allow(clippy::wrong_self_convention)]
1661pub trait AsChar {
1662 fn as_char(self) -> char;
1673
1674 fn is_alpha(self) -> bool;
1683
1684 fn is_alphanum(self) -> bool;
1687 fn is_dec_digit(self) -> bool;
1689 fn is_hex_digit(self) -> bool;
1691 fn is_oct_digit(self) -> bool;
1693 fn len(self) -> usize;
1695 fn is_space(self) -> bool;
1697 fn is_newline(self) -> bool;
1699}
1700
1701impl AsChar for u8 {
1702 #[inline(always)]
1703 fn as_char(self) -> char {
1704 self as char
1705 }
1706 #[inline]
1707 fn is_alpha(self) -> bool {
1708 matches!(self, 0x41..=0x5A | 0x61..=0x7A)
1709 }
1710 #[inline]
1711 fn is_alphanum(self) -> bool {
1712 self.is_alpha() || self.is_dec_digit()
1713 }
1714 #[inline]
1715 fn is_dec_digit(self) -> bool {
1716 matches!(self, 0x30..=0x39)
1717 }
1718 #[inline]
1719 fn is_hex_digit(self) -> bool {
1720 matches!(self, 0x30..=0x39 | 0x41..=0x46 | 0x61..=0x66)
1721 }
1722 #[inline]
1723 fn is_oct_digit(self) -> bool {
1724 matches!(self, 0x30..=0x37)
1725 }
1726 #[inline]
1727 fn len(self) -> usize {
1728 1
1729 }
1730 #[inline]
1731 fn is_space(self) -> bool {
1732 self == b' ' || self == b'\t'
1733 }
1734 #[inline]
1735 fn is_newline(self) -> bool {
1736 self == b'\n'
1737 }
1738}
1739
1740impl AsChar for &u8 {
1741 #[inline(always)]
1742 fn as_char(self) -> char {
1743 (*self).as_char()
1744 }
1745 #[inline(always)]
1746 fn is_alpha(self) -> bool {
1747 (*self).is_alpha()
1748 }
1749 #[inline(always)]
1750 fn is_alphanum(self) -> bool {
1751 (*self).is_alphanum()
1752 }
1753 #[inline(always)]
1754 fn is_dec_digit(self) -> bool {
1755 (*self).is_dec_digit()
1756 }
1757 #[inline(always)]
1758 fn is_hex_digit(self) -> bool {
1759 (*self).is_hex_digit()
1760 }
1761 #[inline(always)]
1762 fn is_oct_digit(self) -> bool {
1763 (*self).is_oct_digit()
1764 }
1765 #[inline(always)]
1766 fn len(self) -> usize {
1767 (*self).len()
1768 }
1769 #[inline(always)]
1770 fn is_space(self) -> bool {
1771 (*self).is_space()
1772 }
1773 #[inline(always)]
1774 fn is_newline(self) -> bool {
1775 (*self).is_newline()
1776 }
1777}
1778
1779impl AsChar for char {
1780 #[inline(always)]
1781 fn as_char(self) -> char {
1782 self
1783 }
1784 #[inline]
1785 fn is_alpha(self) -> bool {
1786 self.is_ascii_alphabetic()
1787 }
1788 #[inline]
1789 fn is_alphanum(self) -> bool {
1790 self.is_alpha() || self.is_dec_digit()
1791 }
1792 #[inline]
1793 fn is_dec_digit(self) -> bool {
1794 self.is_ascii_digit()
1795 }
1796 #[inline]
1797 fn is_hex_digit(self) -> bool {
1798 self.is_ascii_hexdigit()
1799 }
1800 #[inline]
1801 fn is_oct_digit(self) -> bool {
1802 self.is_digit(8)
1803 }
1804 #[inline]
1805 fn len(self) -> usize {
1806 self.len_utf8()
1807 }
1808 #[inline]
1809 fn is_space(self) -> bool {
1810 self == ' ' || self == '\t'
1811 }
1812 #[inline]
1813 fn is_newline(self) -> bool {
1814 self == '\n'
1815 }
1816}
1817
1818impl AsChar for &char {
1819 #[inline(always)]
1820 fn as_char(self) -> char {
1821 (*self).as_char()
1822 }
1823 #[inline(always)]
1824 fn is_alpha(self) -> bool {
1825 (*self).is_alpha()
1826 }
1827 #[inline(always)]
1828 fn is_alphanum(self) -> bool {
1829 (*self).is_alphanum()
1830 }
1831 #[inline(always)]
1832 fn is_dec_digit(self) -> bool {
1833 (*self).is_dec_digit()
1834 }
1835 #[inline(always)]
1836 fn is_hex_digit(self) -> bool {
1837 (*self).is_hex_digit()
1838 }
1839 #[inline(always)]
1840 fn is_oct_digit(self) -> bool {
1841 (*self).is_oct_digit()
1842 }
1843 #[inline(always)]
1844 fn len(self) -> usize {
1845 (*self).len()
1846 }
1847 #[inline(always)]
1848 fn is_space(self) -> bool {
1849 (*self).is_space()
1850 }
1851 #[inline(always)]
1852 fn is_newline(self) -> bool {
1853 (*self).is_newline()
1854 }
1855}
1856
1857pub trait ContainsToken<T> {
1882 fn contains_token(&self, token: T) -> bool;
1884}
1885
1886impl ContainsToken<u8> for u8 {
1887 #[inline(always)]
1888 fn contains_token(&self, token: u8) -> bool {
1889 *self == token
1890 }
1891}
1892
1893impl ContainsToken<&u8> for u8 {
1894 #[inline(always)]
1895 fn contains_token(&self, token: &u8) -> bool {
1896 self.contains_token(*token)
1897 }
1898}
1899
1900impl ContainsToken<char> for u8 {
1901 #[inline(always)]
1902 fn contains_token(&self, token: char) -> bool {
1903 self.as_char() == token
1904 }
1905}
1906
1907impl ContainsToken<&char> for u8 {
1908 #[inline(always)]
1909 fn contains_token(&self, token: &char) -> bool {
1910 self.contains_token(*token)
1911 }
1912}
1913
1914impl<C: AsChar> ContainsToken<C> for char {
1915 #[inline(always)]
1916 fn contains_token(&self, token: C) -> bool {
1917 *self == token.as_char()
1918 }
1919}
1920
1921impl<C, F: Fn(C) -> bool> ContainsToken<C> for F {
1922 #[inline(always)]
1923 fn contains_token(&self, token: C) -> bool {
1924 self(token)
1925 }
1926}
1927
1928impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::Range<C2> {
1929 #[inline(always)]
1930 fn contains_token(&self, token: C1) -> bool {
1931 let start = self.start.clone().as_char();
1932 let end = self.end.clone().as_char();
1933 (start..end).contains(&token.as_char())
1934 }
1935}
1936
1937impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeInclusive<C2> {
1938 #[inline(always)]
1939 fn contains_token(&self, token: C1) -> bool {
1940 let start = self.start().clone().as_char();
1941 let end = self.end().clone().as_char();
1942 (start..=end).contains(&token.as_char())
1943 }
1944}
1945
1946impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeFrom<C2> {
1947 #[inline(always)]
1948 fn contains_token(&self, token: C1) -> bool {
1949 let start = self.start.clone().as_char();
1950 (start..).contains(&token.as_char())
1951 }
1952}
1953
1954impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeTo<C2> {
1955 #[inline(always)]
1956 fn contains_token(&self, token: C1) -> bool {
1957 let end = self.end.clone().as_char();
1958 (..end).contains(&token.as_char())
1959 }
1960}
1961
1962impl<C1: AsChar, C2: AsChar + Clone> ContainsToken<C1> for core::ops::RangeToInclusive<C2> {
1963 #[inline(always)]
1964 fn contains_token(&self, token: C1) -> bool {
1965 let end = self.end.clone().as_char();
1966 (..=end).contains(&token.as_char())
1967 }
1968}
1969
1970impl<C1: AsChar> ContainsToken<C1> for core::ops::RangeFull {
1971 #[inline(always)]
1972 fn contains_token(&self, _token: C1) -> bool {
1973 true
1974 }
1975}
1976
1977impl<C: AsChar> ContainsToken<C> for &'_ [u8] {
1978 #[inline]
1979 fn contains_token(&self, token: C) -> bool {
1980 let token = token.as_char();
1981 self.iter().any(|t| t.as_char() == token)
1982 }
1983}
1984
1985impl<C: AsChar> ContainsToken<C> for &'_ [char] {
1986 #[inline]
1987 fn contains_token(&self, token: C) -> bool {
1988 let token = token.as_char();
1989 self.contains(&token)
1990 }
1991}
1992
1993impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [u8; LEN] {
1994 #[inline]
1995 fn contains_token(&self, token: C) -> bool {
1996 let token = token.as_char();
1997 self.iter().any(|t| t.as_char() == token)
1998 }
1999}
2000
2001impl<const LEN: usize, C: AsChar> ContainsToken<C> for &'_ [char; LEN] {
2002 #[inline]
2003 fn contains_token(&self, token: C) -> bool {
2004 let token = token.as_char();
2005 self.contains(&token)
2006 }
2007}
2008
2009impl<const LEN: usize, C: AsChar> ContainsToken<C> for [u8; LEN] {
2010 #[inline]
2011 fn contains_token(&self, token: C) -> bool {
2012 let token = token.as_char();
2013 self.iter().any(|t| t.as_char() == token)
2014 }
2015}
2016
2017impl<const LEN: usize, C: AsChar> ContainsToken<C> for [char; LEN] {
2018 #[inline]
2019 fn contains_token(&self, token: C) -> bool {
2020 let token = token.as_char();
2021 self.contains(&token)
2022 }
2023}
2024
2025impl<T> ContainsToken<T> for () {
2026 #[inline(always)]
2027 fn contains_token(&self, _token: T) -> bool {
2028 false
2029 }
2030}
2031
2032macro_rules! impl_contains_token_for_tuple {
2033 ($($haystack:ident),+) => (
2034 #[allow(non_snake_case)]
2035 impl<T, $($haystack),+> ContainsToken<T> for ($($haystack),+,)
2036 where
2037 T: Clone,
2038 $($haystack: ContainsToken<T>),+
2039 {
2040 #[inline]
2041 fn contains_token(&self, token: T) -> bool {
2042 let ($(ref $haystack),+,) = *self;
2043 $($haystack.contains_token(token.clone()) || )+ false
2044 }
2045 }
2046 )
2047}
2048
2049macro_rules! impl_contains_token_for_tuples {
2050 ($haystack1:ident, $($haystack:ident),+) => {
2051 impl_contains_token_for_tuples!(__impl $haystack1; $($haystack),+);
2052 };
2053 (__impl $($haystack:ident),+; $haystack1:ident $(,$haystack2:ident)*) => {
2054 impl_contains_token_for_tuple!($($haystack),+);
2055 impl_contains_token_for_tuples!(__impl $($haystack),+, $haystack1; $($haystack2),*);
2056 };
2057 (__impl $($haystack:ident),+;) => {
2058 impl_contains_token_for_tuple!($($haystack),+);
2059 }
2060}
2061
2062impl_contains_token_for_tuples!(
2063 F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21
2064);
2065
2066#[cfg(feature = "simd")]
2067#[inline(always)]
2068fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
2069 memchr::memchr(token, slice)
2070}
2071
2072#[cfg(feature = "simd")]
2073#[inline(always)]
2074fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
2075 memchr::memchr2(token.0, token.1, slice)
2076}
2077
2078#[cfg(feature = "simd")]
2079#[inline(always)]
2080fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
2081 memchr::memchr3(token.0, token.1, token.2, slice)
2082}
2083
2084#[cfg(not(feature = "simd"))]
2085#[inline(always)]
2086fn memchr(token: u8, slice: &[u8]) -> Option<usize> {
2087 slice.iter().position(|t| *t == token)
2088}
2089
2090#[cfg(not(feature = "simd"))]
2091#[inline(always)]
2092fn memchr2(token: (u8, u8), slice: &[u8]) -> Option<usize> {
2093 slice.iter().position(|t| *t == token.0 || *t == token.1)
2094}
2095
2096#[cfg(not(feature = "simd"))]
2097#[inline(always)]
2098fn memchr3(token: (u8, u8, u8), slice: &[u8]) -> Option<usize> {
2099 slice
2100 .iter()
2101 .position(|t| *t == token.0 || *t == token.1 || *t == token.2)
2102}
2103
2104#[inline(always)]
2105fn memmem(slice: &[u8], literal: &[u8]) -> Option<core::ops::Range<usize>> {
2106 match literal.len() {
2107 0 => Some(0..0),
2108 1 => memchr(literal[0], slice).map(|i| i..i + 1),
2109 _ => memmem_(slice, literal),
2110 }
2111}
2112
2113#[inline(always)]
2114fn memmem2(slice: &[u8], literal: (&[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2115 match (literal.0.len(), literal.1.len()) {
2116 (0, _) | (_, 0) => Some(0..0),
2117 (1, 1) => memchr2((literal.0[0], literal.1[0]), slice).map(|i| i..i + 1),
2118 _ => memmem2_(slice, literal),
2119 }
2120}
2121
2122#[inline(always)]
2123fn memmem3(slice: &[u8], literal: (&[u8], &[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2124 match (literal.0.len(), literal.1.len(), literal.2.len()) {
2125 (0, _, _) | (_, 0, _) | (_, _, 0) => Some(0..0),
2126 (1, 1, 1) => memchr3((literal.0[0], literal.1[0], literal.2[0]), slice).map(|i| i..i + 1),
2127 _ => memmem3_(slice, literal),
2128 }
2129}
2130
2131#[cfg(feature = "simd")]
2132#[inline(always)]
2133fn memmem_(slice: &[u8], literal: &[u8]) -> Option<core::ops::Range<usize>> {
2134 let &prefix = match literal.first() {
2135 Some(x) => x,
2136 None => return Some(0..0),
2137 };
2138 #[allow(clippy::manual_find)] for i in memchr::memchr_iter(prefix, slice) {
2140 if slice[i..].starts_with(literal) {
2141 let i_end = i + literal.len();
2142 return Some(i..i_end);
2143 }
2144 }
2145 None
2146}
2147
2148#[cfg(feature = "simd")]
2149fn memmem2_(slice: &[u8], literal: (&[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2150 let prefix = match (literal.0.first(), literal.1.first()) {
2151 (Some(&a), Some(&b)) => (a, b),
2152 _ => return Some(0..0),
2153 };
2154 #[allow(clippy::manual_find)] for i in memchr::memchr2_iter(prefix.0, prefix.1, slice) {
2156 let subslice = &slice[i..];
2157 if subslice.starts_with(literal.0) {
2158 let i_end = i + literal.0.len();
2159 return Some(i..i_end);
2160 }
2161 if subslice.starts_with(literal.1) {
2162 let i_end = i + literal.1.len();
2163 return Some(i..i_end);
2164 }
2165 }
2166 None
2167}
2168
2169#[cfg(feature = "simd")]
2170fn memmem3_(slice: &[u8], literal: (&[u8], &[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2171 let prefix = match (literal.0.first(), literal.1.first(), literal.2.first()) {
2172 (Some(&a), Some(&b), Some(&c)) => (a, b, c),
2173 _ => return Some(0..0),
2174 };
2175 #[allow(clippy::manual_find)] for i in memchr::memchr3_iter(prefix.0, prefix.1, prefix.2, slice) {
2177 let subslice = &slice[i..];
2178 if subslice.starts_with(literal.0) {
2179 let i_end = i + literal.0.len();
2180 return Some(i..i_end);
2181 }
2182 if subslice.starts_with(literal.1) {
2183 let i_end = i + literal.1.len();
2184 return Some(i..i_end);
2185 }
2186 if subslice.starts_with(literal.2) {
2187 let i_end = i + literal.2.len();
2188 return Some(i..i_end);
2189 }
2190 }
2191 None
2192}
2193
2194#[cfg(not(feature = "simd"))]
2195fn memmem_(slice: &[u8], literal: &[u8]) -> Option<core::ops::Range<usize>> {
2196 for i in 0..slice.len() {
2197 let subslice = &slice[i..];
2198 if subslice.starts_with(literal) {
2199 let i_end = i + literal.len();
2200 return Some(i..i_end);
2201 }
2202 }
2203 None
2204}
2205
2206#[cfg(not(feature = "simd"))]
2207fn memmem2_(slice: &[u8], literal: (&[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2208 for i in 0..slice.len() {
2209 let subslice = &slice[i..];
2210 if subslice.starts_with(literal.0) {
2211 let i_end = i + literal.0.len();
2212 return Some(i..i_end);
2213 }
2214 if subslice.starts_with(literal.1) {
2215 let i_end = i + literal.1.len();
2216 return Some(i..i_end);
2217 }
2218 }
2219 None
2220}
2221
2222#[cfg(not(feature = "simd"))]
2223fn memmem3_(slice: &[u8], literal: (&[u8], &[u8], &[u8])) -> Option<core::ops::Range<usize>> {
2224 for i in 0..slice.len() {
2225 let subslice = &slice[i..];
2226 if subslice.starts_with(literal.0) {
2227 let i_end = i + literal.0.len();
2228 return Some(i..i_end);
2229 }
2230 if subslice.starts_with(literal.1) {
2231 let i_end = i + literal.1.len();
2232 return Some(i..i_end);
2233 }
2234 if subslice.starts_with(literal.2) {
2235 let i_end = i + literal.2.len();
2236 return Some(i..i_end);
2237 }
2238 }
2239 None
2240}