by/
byte_str.rs

1// Copyright 2018 Eduardo Sánchez Muñoz
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use 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/// Borrowed reference to a byte string. It provides similar functionality as `str`
24/// and `[u8]`.
25#[derive(PartialEq, Eq)]
26pub struct ByteStr {
27    inner: [u8],
28}
29
30impl ByteStr {
31    /// Creates an empty `ByteStr`.
32    #[inline]
33    pub fn empty<'a>() -> &'a Self {
34        Self::from_slice(&[])
35    }
36    
37    /// Creates an empty mutable `ByteStr`.
38    #[inline]
39    pub fn empty_mut<'a>() -> &'a mut Self {
40        Self::from_slice_mut(&mut [])
41    }
42    
43    /// Creates a `ByteStr` from a byte slice.
44    #[inline]
45    pub fn from_slice(bytes: &[u8]) -> &Self {
46        unsafe { core::mem::transmute(bytes) }
47    }
48    
49    /// Create a mutable `ByteStr` from a byte slice.
50    #[inline]
51    pub fn from_slice_mut(bytes: &mut [u8]) -> &mut Self {
52        unsafe { core::mem::transmute(bytes) }
53    }
54    
55    /// Forms a `ByteStr` from a pointer and a length.
56    #[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    /// Forms a mutable `ByteStr` from a pointer and a length.
62    #[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    /// Converts `self` into a byte slice.
68    #[inline]
69    pub fn as_slice(&self) -> &[u8] {
70        &self.inner
71    }
72    
73    /// Converts `self` into a mutable byte slice.
74    #[inline]
75    pub fn as_mut_slice(&mut self) -> &mut [u8] {
76        &mut self.inner
77    }
78    
79    /// Copies the `self` into a `Vec`.
80    #[cfg(not(feature="no_std"))]
81    #[inline]
82    pub fn to_vec(&self) -> Vec<u8> {
83        self.as_slice().to_vec()
84    }
85    
86    /// Copies the `self` into a `ByteString`.
87    #[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    /// Converts `self` into a boxed slice without clones or allocation.
94    #[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    /// Converts `self` into a vector without clones or allocation.
100    #[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    /// Converts `self` into a `ByteString` without clones or allocation.
106    #[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    /// Returns the length of `self`.
112    #[inline]
113    pub fn len(&self) -> usize {
114        self.as_slice().len()
115    }
116    
117    /// Returns `true` if the length of `self` is zero.
118    #[inline]
119    pub fn is_empty(&self) -> bool {
120        self.len() == 0
121    }
122    
123    /// Converts `self` into a raw pointer that points to the first byte of the string.
124    #[inline]
125    pub fn as_ptr(&self) -> *const u8 {
126        self.as_slice().as_ptr()
127    }
128    
129    /// Converts `self` into a mutable raw pointer that points to the first byte of the string.
130    #[inline]
131    pub fn as_mut_ptr(&mut self) -> *mut u8 {
132        self.as_mut_slice().as_mut_ptr()
133    }
134    
135    /// Returns a reference to an element of the slice, or `None` if the
136    /// index is out of bounds.
137    #[inline]
138    pub fn get(&self, index: usize) -> Option<&u8> {
139        self.as_slice().get(index)
140    }
141    
142    /// Returns a mutable reference to an element of the slice, or `None` if the
143    /// index is out of bounds.
144    #[inline]
145    pub fn get_mut(&mut self, index: usize) -> Option<&mut u8> {
146        self.as_mut_slice().get_mut(index)
147    }
148    
149    /// Returns a reference to the first byte of the string, or `None` if it is empty.
150    #[inline]
151    pub fn first(&self) -> Option<&u8> {
152        self.as_slice().first()
153    }
154    
155    /// Returns a mutable reference to the first byte of the string, or `None` if it is empty.
156    #[inline]
157    pub fn first_mut(&mut self) -> Option<&mut u8> {
158        self.as_mut_slice().first_mut()
159    }
160    
161    /// Returns a reference to the last byte of the string, or `None` if it is empty.
162    #[inline]
163    pub fn last(&self) -> Option<&u8> {
164        self.as_slice().last()
165    }
166    
167    /// Returns a mutable reference to the last byte of the string, or `None` if it is empty.
168    #[inline]
169    pub fn last_mut(&mut self) -> Option<&mut u8> {
170        self.as_mut_slice().last_mut()
171    }
172    
173    /// Returns the first and all the rest of the bytes of the slice, or `None` if it is empty.
174    #[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    /// Returns the first and all the rest of the bytes of the slice, or `None` if it is empty.
180    #[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    /// Returns the last and all the rest of the bytes of the slice, or `None` if it is empty.
186    #[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    /// Returns the last and all the rest of the bytes of the slice, or `None` if it is empty.
192    #[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    /// Returns an iterator over the string.
198    #[inline]
199    pub fn iter<'a>(&'a self) -> core::slice::Iter<'a, u8> {
200        self.as_slice().iter()
201    }
202    
203    /// Returns an iterator that allows modifying each value.
204    #[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    /// Returns an iterator over all contiguous windows of length `size`.
210    /// The windows overlap. If the string is shorter than `size`, the
211    /// iterator returns no values.
212    ///
213    /// Similar to `slice::windows()`.
214    #[inline]
215    pub fn windows<'a>(&'a self, size: usize) -> iterators::Windows<'a> {
216        iterators::Windows::new(self, size)
217    }
218    
219    /// Returns an iterator over `size` bytes of the string at a time. The chunks do not
220    /// overlap. If size does not divide the length of the slice, then the last chunk will
221    /// not have length `size`.
222    ///
223    /// Similar to `slice::chunks()`.
224    #[inline]
225    pub fn chunks<'a>(&'a self, size: usize) -> iterators::Chunks<'a> {
226        iterators::Chunks::new(self, size)
227    }
228    
229    /// Returns an iterator over `size` elements of the slice at a time. The chunks are mutable
230    /// strings and do not overlap. If `size` does not divide the length of the slice, then the
231    /// last chunk will not have length `size`.
232    ///
233    /// Similar to `slice::chunks_mut()`.
234    #[inline]
235    pub fn chunks_mut<'a>(&'a mut self, size: usize) -> iterators::ChunksMut<'a> {
236        iterators::ChunksMut::new(self, size)
237    }
238    
239    /// Divides one string into two at an index.
240    ///
241    /// The first will contain all indices from `[0, mid)` (excluding the index `mid` itself) and
242    /// the second will contain all indices from `[mid, len)` (excluding the index `len` itself).
243    ///
244    /// Similar to `slice::split_at()`.
245    ///
246    /// # Panics
247    ///
248    /// Panics if `mid > len`.
249    #[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    /// Divides one `&mut` string into two at an index.
256    ///
257    /// The first will contain all indices from `[0, mid)` (excluding the index `mid` itself) and
258    /// the second will contain all indices from `[mid, len)` (excluding the index `len` itself).
259    ///
260    /// Similar to `slice::split_at_mut()`.
261    ///
262    /// # Panics
263    ///
264    /// Panics if `mid > len`.
265    #[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    /// Returns an iterator over substrings of this string, separated by a matcher.
272    #[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    /// Returns an iterator over mutable substrings of this string, separated by a matcher.
280    #[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    /// Returns an iterator over substrings of this string, separated by a matcher,
288    /// starting at the end of the slice and working backwards.
289    #[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    /// Returns an iterator over mutable substrings of this string, separated by a matcher,
297    /// starting at the end of the slice and working backwards.
298    #[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    /// Returns an iterator over substrings of this string, separated by a matcher, returning
306    /// at most `n` items.
307    ///
308    /// If `n` substrings are returned, the last substring will contain the remainder of the string.
309    #[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    /// Returns an iterator over mutable substrings of this string, separated by a matcher, returning
317    /// at most `n` items.
318    ///
319    /// If `n` substrings are returned, the last substring will contain the remainder of the string.
320    #[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    /// Returns an iterator over substrings of this string, separated by a matcher and stating from
328    /// the end of the string, returning at most `n` items.
329    ///
330    /// If `n` substrings are returned, the last substring will contain the remainder of the string.
331    #[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    /// Returns an iterator over mutable substrings of this string, separated by a matcher and stating from
339    /// the end of the string, returning at most `n` items.
340    ///
341    /// If `n` substrings are returned, the last substring will contain the remainder of the string.
342    #[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    /// Returns an iterator over the disjoint matches within the given string.
350    #[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    /// Returns an iterator over the mutable disjoint matches within the given string.
358    #[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    /// Returns an iterator over the disjoint matches within the given string, yielded in reverse order.
366    #[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    /// Returns an iterator over the mutable disjoint matches within the given string, yielded
374    /// in reverse order.
375    #[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    /// Returns an iterator over the disjoint matches within the given string, as well as the index
383    /// that the match starts at.
384    #[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    /// Returns an iterator over the mutable disjoint matches within the given string, as well as
392    /// the index that the match starts at.
393    #[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    /// Returns an iterator over the disjoint matches within the given string, yielded in reverse order,
401    /// as well as the index that the match starts at.
402    #[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    /// Returns an iterator over the mutable disjoint matches within the given string, yielded in reverse
410    /// order, as well as the index that the match starts at.
411    #[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    /// Returns `true` if the string contains a substring that matches the given matcher.
419    #[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    /// Returns `true` if the string beginning a matches the given matcher.
427    #[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    /// Returns `true` if the string ending a matches the given matcher.
435    #[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    /// Returns the byte index of the first character of `self` that matches the
443    /// matcher or `None` it it doesn't match.
444    #[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    /// Returns the byte index of the last character of `self` that matches the
452    /// matcher or `None` it it doesn't match.
453    #[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    /// Swaps two bytes in the string, indexed by `a` and `b`.
461    ///
462    /// # Panics
463    ///
464    /// Panics if `a` or `b` are out of bounds.
465    #[inline]
466    pub fn swap(&mut self, a: usize, b: usize) {
467        self.as_mut_slice().swap(a, b);
468    }
469    
470    /// Reverses the order of bytes in the slice.
471    #[inline]
472    pub fn reverse(&mut self) {
473        self.as_mut_slice().reverse();
474    }
475    
476    /// Copies all elements from `src` into `self`, using a memcpy.
477    ///
478    /// The length of `src` must be the same as `self`.
479    #[inline]
480    pub fn copy_from_slice(&mut self, src: &[u8]) {
481        self.as_mut_slice().copy_from_slice(src);
482    }
483    
484    /// Copies all elements from `src` into `self`, using a memcpy.
485    ///
486    /// The length of `src` must be the same as `self`.
487    #[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
493// Default
494impl<'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
508// Debug
509impl 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// ToOwned
543#[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
553// AsRef
554impl 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
568// AsMut
569impl 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
583// PartialEq
584impl<'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
698// Index
699impl 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
744// IndexMux
745impl 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
780// IntoIterator
781impl<'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}