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