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