1use core;
9#[cfg(not(feature="no_std"))]
10use std;
11
12#[cfg(not(feature="no_std"))]
13use ByteString;
14
15use iterators;
16
17use IntoMatcher;
18use PrefixMatcher;
19use SufixMatcher;
20use ForwardSearcher;
21use ReverseSearcher;
22
23#[derive(PartialEq, Eq)]
26pub struct ByteStr {
27 inner: [u8],
28}
29
30impl ByteStr {
31 #[inline]
33 pub fn empty<'a>() -> &'a Self {
34 Self::from_slice(&[])
35 }
36
37 #[inline]
39 pub fn empty_mut<'a>() -> &'a mut Self {
40 Self::from_slice_mut(&mut [])
41 }
42
43 #[inline]
45 pub fn from_slice(bytes: &[u8]) -> &Self {
46 unsafe { core::mem::transmute(bytes) }
47 }
48
49 #[inline]
51 pub fn from_slice_mut(bytes: &mut [u8]) -> &mut Self {
52 unsafe { core::mem::transmute(bytes) }
53 }
54
55 #[inline]
57 pub unsafe fn from_raw_parts<'a>(ptr: *const u8, len: usize) -> &'a Self {
58 ByteStr::from_slice(core::slice::from_raw_parts(ptr, len))
59 }
60
61 #[inline]
63 pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a mut Self {
64 ByteStr::from_slice_mut(core::slice::from_raw_parts_mut(ptr, len))
65 }
66
67 #[inline]
69 pub fn as_slice(&self) -> &[u8] {
70 &self.inner
71 }
72
73 #[inline]
75 pub fn as_mut_slice(&mut self) -> &mut [u8] {
76 &mut self.inner
77 }
78
79 #[cfg(not(feature="no_std"))]
81 #[inline]
82 pub fn to_vec(&self) -> Vec<u8> {
83 self.as_slice().to_vec()
84 }
85
86 #[cfg(not(feature="no_std"))]
88 #[inline]
89 pub fn to_byte_string(&self) -> ByteString {
90 ByteString::from_vec(self.to_vec())
91 }
92
93 #[cfg(not(feature="no_std"))]
95 pub fn into_boxed_slice(self: Box<Self>) -> Box<[u8]> {
96 unsafe { Box::from_raw(Box::into_raw(self) as *mut [u8]) }
97 }
98
99 #[cfg(not(feature="no_std"))]
101 pub fn into_vec(self: Box<Self>) -> Vec<u8> {
102 self.into_boxed_slice().into_vec()
103 }
104
105 #[cfg(not(feature="no_std"))]
107 pub fn into_byte_string(self: Box<Self>) -> ByteString {
108 ByteString::from_vec(self.into_vec())
109 }
110
111 #[inline]
113 pub fn len(&self) -> usize {
114 self.as_slice().len()
115 }
116
117 #[inline]
119 pub fn is_empty(&self) -> bool {
120 self.len() == 0
121 }
122
123 #[inline]
125 pub fn as_ptr(&self) -> *const u8 {
126 self.as_slice().as_ptr()
127 }
128
129 #[inline]
131 pub fn as_mut_ptr(&mut self) -> *mut u8 {
132 self.as_mut_slice().as_mut_ptr()
133 }
134
135 #[inline]
138 pub fn get(&self, index: usize) -> Option<&u8> {
139 self.as_slice().get(index)
140 }
141
142 #[inline]
145 pub fn get_mut(&mut self, index: usize) -> Option<&mut u8> {
146 self.as_mut_slice().get_mut(index)
147 }
148
149 #[inline]
151 pub fn first(&self) -> Option<&u8> {
152 self.as_slice().first()
153 }
154
155 #[inline]
157 pub fn first_mut(&mut self) -> Option<&mut u8> {
158 self.as_mut_slice().first_mut()
159 }
160
161 #[inline]
163 pub fn last(&self) -> Option<&u8> {
164 self.as_slice().last()
165 }
166
167 #[inline]
169 pub fn last_mut(&mut self) -> Option<&mut u8> {
170 self.as_mut_slice().last_mut()
171 }
172
173 #[inline]
175 pub fn split_first(&self) -> Option<(&u8, &ByteStr)> {
176 self.as_slice().split_first().map(|(f, r)| (f, Self::from_slice(r)))
177 }
178
179 #[inline]
181 pub fn split_first_mut(&mut self) -> Option<(&mut u8, &mut ByteStr)> {
182 self.as_mut_slice().split_first_mut().map(|(f, r)| (f, Self::from_slice_mut(r)))
183 }
184
185 #[inline]
187 pub fn split_last(&self) -> Option<(&u8, &ByteStr)> {
188 self.as_slice().split_last().map(|(f, r)| (f, Self::from_slice(r)))
189 }
190
191 #[inline]
193 pub fn split_last_mut(&mut self) -> Option<(&mut u8, &mut ByteStr)> {
194 self.as_mut_slice().split_last_mut().map(|(f, r)| (f, Self::from_slice_mut(r)))
195 }
196
197 #[inline]
199 pub fn iter<'a>(&'a self) -> core::slice::Iter<'a, u8> {
200 self.as_slice().iter()
201 }
202
203 #[inline]
205 pub fn iter_mut<'a>(&'a mut self) -> core::slice::IterMut<'a, u8> {
206 self.as_mut_slice().iter_mut()
207 }
208
209 #[inline]
215 pub fn windows<'a>(&'a self, size: usize) -> iterators::Windows<'a> {
216 iterators::Windows::new(self, size)
217 }
218
219 #[inline]
225 pub fn chunks<'a>(&'a self, size: usize) -> iterators::Chunks<'a> {
226 iterators::Chunks::new(self, size)
227 }
228
229 #[inline]
235 pub fn chunks_mut<'a>(&'a mut self, size: usize) -> iterators::ChunksMut<'a> {
236 iterators::ChunksMut::new(self, size)
237 }
238
239 #[inline]
250 pub fn split_at(&self, mid: usize) -> (&ByteStr, &ByteStr) {
251 let (first, second) = self.as_slice().split_at(mid);
252 (ByteStr::from_slice(first), ByteStr::from_slice(second))
253 }
254
255 #[inline]
266 pub fn split_at_mut(&mut self, mid: usize) -> (&mut ByteStr, &mut ByteStr) {
267 let (first, second) = self.as_mut_slice().split_at_mut(mid);
268 (ByteStr::from_slice_mut(first), ByteStr::from_slice_mut(second))
269 }
270
271 #[inline]
273 pub fn split<'a, M: IntoMatcher>(&'a self, m: M) -> iterators::Split<'a, M::Matcher>
274 where <M as IntoMatcher>::Matcher: ForwardSearcher
275 {
276 iterators::Split::new(self, m.into_matcher())
277 }
278
279 #[inline]
281 pub fn split_mut<'a, M: IntoMatcher>(&'a mut self, m: M) -> iterators::SplitMut<'a, M::Matcher>
282 where <M as IntoMatcher>::Matcher: ForwardSearcher
283 {
284 iterators::SplitMut::new(self, m.into_matcher())
285 }
286
287 #[inline]
290 pub fn rsplit<'a, M: IntoMatcher>(&'a self, m: M) -> iterators::RSplit<'a, M::Matcher>
291 where <M as IntoMatcher>::Matcher: ReverseSearcher
292 {
293 iterators::RSplit::new(self, m.into_matcher())
294 }
295
296 #[inline]
299 pub fn rsplit_mut<'a, M: IntoMatcher>(&'a mut self, m: M) -> iterators::RSplitMut<'a, M::Matcher>
300 where <M as IntoMatcher>::Matcher: ReverseSearcher
301 {
302 iterators::RSplitMut::new(self, m.into_matcher())
303 }
304
305 #[inline]
310 pub fn splitn<'a, M: IntoMatcher>(&'a self, n: usize, m: M) -> iterators::SplitN<'a, M::Matcher>
311 where <M as IntoMatcher>::Matcher: ForwardSearcher
312 {
313 iterators::SplitN::new(self, n, m.into_matcher())
314 }
315
316 #[inline]
321 pub fn splitn_mut<'a, M: IntoMatcher>(&'a mut self, n: usize, m: M) -> iterators::SplitNMut<'a, M::Matcher>
322 where <M as IntoMatcher>::Matcher: ForwardSearcher
323 {
324 iterators::SplitNMut::new(self, n, m.into_matcher())
325 }
326
327 #[inline]
332 pub fn rsplitn<'a, M: IntoMatcher>(&'a self, n: usize, m: M) -> iterators::RSplitN<'a, M::Matcher>
333 where <M as IntoMatcher>::Matcher: ReverseSearcher
334 {
335 iterators::RSplitN::new(self, n, m.into_matcher())
336 }
337
338 #[inline]
343 pub fn rsplitn_mut<'a, M: IntoMatcher>(&'a mut self, n: usize, m: M) -> iterators::RSplitNMut<'a, M::Matcher>
344 where <M as IntoMatcher>::Matcher: ReverseSearcher
345 {
346 iterators::RSplitNMut::new(self, n, m.into_matcher())
347 }
348
349 #[inline]
351 pub fn matches<'a, M: IntoMatcher>(&'a self, m: M) -> iterators::Matches<'a, M::Matcher>
352 where <M as IntoMatcher>::Matcher: ForwardSearcher
353 {
354 iterators::Matches::new(self, m.into_matcher())
355 }
356
357 #[inline]
359 pub fn matches_mut<'a, M: IntoMatcher>(&'a mut self, m: M) -> iterators::MatchesMut<'a, M::Matcher>
360 where <M as IntoMatcher>::Matcher: ForwardSearcher
361 {
362 iterators::MatchesMut::new(self, m.into_matcher())
363 }
364
365 #[inline]
367 pub fn rmatches<'a, M: IntoMatcher>(&'a self, m: M) -> iterators::RMatches<'a, M::Matcher>
368 where <M as IntoMatcher>::Matcher: ReverseSearcher
369 {
370 iterators::RMatches::new(self, m.into_matcher())
371 }
372
373 #[inline]
376 pub fn rmatches_mut<'a, M: IntoMatcher>(&'a mut self, m: M) -> iterators::RMatchesMut<'a, M::Matcher>
377 where <M as IntoMatcher>::Matcher: ReverseSearcher
378 {
379 iterators::RMatchesMut::new(self, m.into_matcher())
380 }
381
382 #[inline]
385 pub fn match_indices<'a, M: IntoMatcher>(&'a self, m: M) -> iterators::MatchIndices<'a, M::Matcher>
386 where <M as IntoMatcher>::Matcher: ForwardSearcher
387 {
388 iterators::MatchIndices::new(self, m.into_matcher())
389 }
390
391 #[inline]
394 pub fn match_indices_mut<'a, M: IntoMatcher>(&'a mut self, m: M) -> iterators::MatchIndicesMut<'a, M::Matcher>
395 where <M as IntoMatcher>::Matcher: ForwardSearcher
396 {
397 iterators::MatchIndicesMut::new(self, m.into_matcher())
398 }
399
400 #[inline]
403 pub fn rmatch_indices<'a, M: IntoMatcher>(&'a self, m: M) -> iterators::RMatchIndices<'a, M::Matcher>
404 where <M as IntoMatcher>::Matcher: ReverseSearcher
405 {
406 iterators::RMatchIndices::new(self, m.into_matcher())
407 }
408
409 #[inline]
412 pub fn rmatch_indices_mut<'a, M: IntoMatcher>(&'a mut self, m: M) -> iterators::RMatchIndicesMut<'a, M::Matcher>
413 where <M as IntoMatcher>::Matcher: ReverseSearcher
414 {
415 iterators::RMatchIndicesMut::new(self, m.into_matcher())
416 }
417
418 #[inline]
420 pub fn contains<M: IntoMatcher>(&self, m: M) -> bool
421 where <M as IntoMatcher>::Matcher: ForwardSearcher
422 {
423 m.into_matcher().find(self).is_some()
424 }
425
426 #[inline]
428 pub fn starts_with<M: IntoMatcher>(&self, m: M) -> bool
429 where <M as IntoMatcher>::Matcher: PrefixMatcher
430 {
431 m.into_matcher().is_prefix_of(self)
432 }
433
434 #[inline]
436 pub fn ends_with<M: IntoMatcher>(&self, m: M) -> bool
437 where <M as IntoMatcher>::Matcher: SufixMatcher
438 {
439 m.into_matcher().is_sufix_of(self)
440 }
441
442 #[inline]
445 pub fn find<M: IntoMatcher>(&self, m: M) -> Option<usize>
446 where <M as IntoMatcher>::Matcher: ForwardSearcher
447 {
448 m.into_matcher().find(self).map(|(a, _)| a)
449 }
450
451 #[inline]
454 pub fn rfind<M: IntoMatcher>(&self, m: M) -> Option<usize>
455 where <M as IntoMatcher>::Matcher: ReverseSearcher
456 {
457 m.into_matcher().rfind(self).map(|(_, b)| b)
458 }
459
460 #[inline]
466 pub fn swap(&mut self, a: usize, b: usize) {
467 self.as_mut_slice().swap(a, b);
468 }
469
470 #[inline]
472 pub fn reverse(&mut self) {
473 self.as_mut_slice().reverse();
474 }
475
476 #[inline]
480 pub fn copy_from_slice(&mut self, src: &[u8]) {
481 self.as_mut_slice().copy_from_slice(src);
482 }
483
484 #[inline]
488 pub fn copy_from_byte_str(&mut self, src: &ByteStr) {
489 self.as_mut_slice().copy_from_slice(src.as_slice());
490 }
491}
492
493impl<'a> Default for &'a ByteStr {
495 #[inline]
496 fn default() -> Self {
497 ByteStr::empty()
498 }
499}
500
501impl<'a> Default for &'a mut ByteStr {
502 #[inline]
503 fn default() -> Self {
504 ByteStr::empty_mut()
505 }
506}
507
508impl core::fmt::Debug for ByteStr {
510 fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
511 use core::fmt::Write;
512
513 fn to_hex(nibble: u8) -> u8 {
514 if nibble < 10 {
515 b'0' + nibble
516 } else {
517 b'a' + nibble - 10
518 }
519 }
520
521 f.write_str("b\"")?;
522 for &byte in self.iter() {
523 match byte {
524 b'\t' => f.write_str("\\t")?,
525 b'\r' => f.write_str("\\r")?,
526 b'\n' => f.write_str("\\n")?,
527 b'\\' => f.write_str("\\\\")?,
528 b'"' => f.write_str("\\\"")?,
529 0x20 ... 0x7E => f.write_char(byte as char)?,
530 _ => {
531 f.write_str("\\x")?;
532 f.write_char(to_hex(byte >> 4) as char)?;
533 f.write_char(to_hex(byte & 0xF) as char)?;
534 }
535 }
536 }
537 f.write_char('"')?;
538 Ok(())
539 }
540}
541
542#[cfg(not(feature="no_std"))]
544impl std::borrow::ToOwned for ByteStr {
545 type Owned = ByteString;
546
547 #[inline]
548 fn to_owned(&self) -> ByteString {
549 self.to_byte_string()
550 }
551}
552
553impl core::convert::AsRef<ByteStr> for ByteStr {
555 #[inline]
556 fn as_ref(&self) -> &ByteStr {
557 self
558 }
559}
560
561impl core::convert::AsRef<[u8]> for ByteStr {
562 #[inline]
563 fn as_ref(&self) -> &[u8] {
564 self.as_slice()
565 }
566}
567
568impl core::convert::AsMut<ByteStr> for ByteStr {
570 #[inline]
571 fn as_mut(&mut self) -> &mut ByteStr {
572 self
573 }
574}
575
576impl core::convert::AsMut<[u8]> for ByteStr {
577 #[inline]
578 fn as_mut(&mut self) -> &mut [u8] {
579 self.as_mut_slice()
580 }
581}
582
583impl<'a> core::cmp::PartialEq<ByteStr> for &'a ByteStr {
585 #[inline]
586 fn eq(&self, other: &ByteStr) -> bool {
587 self.as_slice() == other.as_slice()
588 }
589}
590
591impl core::cmp::PartialEq<[u8]> for ByteStr {
592 #[inline]
593 fn eq(&self, other: &[u8]) -> bool {
594 self.as_slice() == other
595 }
596}
597
598impl<'a> core::cmp::PartialEq<[u8]> for &'a ByteStr {
599 #[inline]
600 fn eq(&self, other: &[u8]) -> bool {
601 self.as_slice() == other
602 }
603}
604
605macro_rules! impl_partial_eq_array {
606 ($size:expr) => {
607 impl core::cmp::PartialEq<[u8; $size]> for ByteStr {
608 #[inline]
609 fn eq(&self, other: &[u8; $size]) -> bool {
610 self.as_slice() == other
611 }
612 }
613
614 impl<'a> core::cmp::PartialEq<[u8; $size]> for &'a ByteStr {
615 #[inline]
616 fn eq(&self, other: &[u8; $size]) -> bool {
617 self.as_slice() == other
618 }
619 }
620 }
621}
622
623impl_partial_eq_array!(0);
624impl_partial_eq_array!(1);
625impl_partial_eq_array!(2);
626impl_partial_eq_array!(3);
627impl_partial_eq_array!(4);
628impl_partial_eq_array!(5);
629impl_partial_eq_array!(6);
630impl_partial_eq_array!(7);
631impl_partial_eq_array!(8);
632impl_partial_eq_array!(9);
633impl_partial_eq_array!(10);
634impl_partial_eq_array!(11);
635impl_partial_eq_array!(12);
636impl_partial_eq_array!(13);
637impl_partial_eq_array!(14);
638impl_partial_eq_array!(15);
639impl_partial_eq_array!(16);
640impl_partial_eq_array!(17);
641impl_partial_eq_array!(18);
642impl_partial_eq_array!(19);
643impl_partial_eq_array!(20);
644impl_partial_eq_array!(21);
645impl_partial_eq_array!(22);
646impl_partial_eq_array!(23);
647impl_partial_eq_array!(24);
648impl_partial_eq_array!(25);
649impl_partial_eq_array!(26);
650impl_partial_eq_array!(27);
651impl_partial_eq_array!(28);
652impl_partial_eq_array!(29);
653impl_partial_eq_array!(30);
654impl_partial_eq_array!(31);
655impl_partial_eq_array!(32);
656
657#[cfg(not(feature="no_std"))]
658impl core::cmp::PartialEq<ByteString> for ByteStr {
659 #[inline]
660 fn eq(&self, other: &ByteString) -> bool {
661 self.as_slice() == other.as_slice()
662 }
663}
664
665#[cfg(not(feature="no_std"))]
666impl<'a> core::cmp::PartialEq<ByteString> for &'a ByteStr {
667 #[inline]
668 fn eq(&self, other: &ByteString) -> bool {
669 self.as_slice() == other.as_slice()
670 }
671}
672
673#[cfg(not(feature="no_std"))]
674impl<'b> core::cmp::PartialEq<std::borrow::Cow<'b, ByteStr>> for ByteStr {
675 #[inline]
676 fn eq(&self, other: &std::borrow::Cow<'b, ByteStr>) -> bool {
677 self.as_slice() == other.as_slice()
678 }
679}
680
681#[cfg(not(feature="no_std"))]
682impl<'a, 'b> core::cmp::PartialEq<std::borrow::Cow<'b, ByteStr>> for &'a ByteStr {
683 #[inline]
684 fn eq(&self, other: &std::borrow::Cow<'b, ByteStr>) -> bool {
685 self.as_slice() == other.as_slice()
686 }
687}
688
689impl<'a, T: ?Sized> core::cmp::PartialEq<&'a T> for ByteStr
690 where ByteStr: core::cmp::PartialEq<T>
691{
692 #[inline]
693 fn eq(&self, other: &&'a T) -> bool {
694 self == *other
695 }
696}
697
698impl core::ops::Index<usize> for ByteStr {
700 type Output = u8;
701
702 #[inline]
703 fn index(&self, index: usize) -> &u8 {
704 &self.as_slice()[index]
705 }
706}
707
708impl core::ops::Index<core::ops::Range<usize>> for ByteStr {
709 type Output = ByteStr;
710
711 #[inline]
712 fn index(&self, index: core::ops::Range<usize>) -> &ByteStr {
713 ByteStr::from_slice(&self.as_slice()[index])
714 }
715}
716
717impl core::ops::Index<core::ops::RangeFrom<usize>> for ByteStr {
718 type Output = ByteStr;
719
720 #[inline]
721 fn index(&self, index: core::ops::RangeFrom<usize>) -> &ByteStr {
722 ByteStr::from_slice(&self.as_slice()[index])
723 }
724}
725
726impl core::ops::Index<core::ops::RangeTo<usize>> for ByteStr {
727 type Output = ByteStr;
728
729 #[inline]
730 fn index(&self, index: core::ops::RangeTo<usize>) -> &ByteStr {
731 ByteStr::from_slice(&self.as_slice()[index])
732 }
733}
734
735impl core::ops::Index<core::ops::RangeFull> for ByteStr {
736 type Output = ByteStr;
737
738 #[inline]
739 fn index(&self, index: core::ops::RangeFull) -> &ByteStr {
740 ByteStr::from_slice(&self.as_slice()[index])
741 }
742}
743
744impl core::ops::IndexMut<usize> for ByteStr {
746 #[inline]
747 fn index_mut(&mut self, index: usize) -> &mut u8 {
748 &mut self.as_mut_slice()[index]
749 }
750}
751
752impl core::ops::IndexMut<core::ops::Range<usize>> for ByteStr {
753 #[inline]
754 fn index_mut(&mut self, index: core::ops::Range<usize>) -> &mut ByteStr {
755 ByteStr::from_slice_mut(&mut self.as_mut_slice()[index])
756 }
757}
758
759impl core::ops::IndexMut<core::ops::RangeFrom<usize>> for ByteStr {
760 #[inline]
761 fn index_mut(&mut self, index: core::ops::RangeFrom<usize>) -> &mut ByteStr {
762 ByteStr::from_slice_mut(&mut self.as_mut_slice()[index])
763 }
764}
765
766impl core::ops::IndexMut<core::ops::RangeTo<usize>> for ByteStr {
767 #[inline]
768 fn index_mut(&mut self, index: core::ops::RangeTo<usize>) -> &mut ByteStr {
769 ByteStr::from_slice_mut(&mut self.as_mut_slice()[index])
770 }
771}
772
773impl core::ops::IndexMut<core::ops::RangeFull> for ByteStr {
774 #[inline]
775 fn index_mut(&mut self, index: core::ops::RangeFull) -> &mut ByteStr {
776 ByteStr::from_slice_mut(&mut self.as_mut_slice()[index])
777 }
778}
779
780impl<'a> core::iter::IntoIterator for &'a ByteStr {
782 type Item = &'a u8;
783 type IntoIter = core::slice::Iter<'a, u8>;
784
785 #[inline]
786 fn into_iter(self) -> Self::IntoIter {
787 self.iter()
788 }
789}
790
791impl<'a> core::iter::IntoIterator for &'a mut ByteStr {
792 type Item = &'a mut u8;
793 type IntoIter = core::slice::IterMut<'a, u8>;
794
795 #[inline]
796 fn into_iter(self) -> Self::IntoIter {
797 self.iter_mut()
798 }
799}