1 use core::mem;
2 
3 /// A wrapper for `&[u8]` that provides convenient string oriented trait impls.
4 ///
5 /// If you need ownership or a growable byte string buffer, then use
6 /// [`BString`](struct.BString.html).
7 ///
8 /// Using a `&BStr` is just like using a `&[u8]`, since `BStr`
9 /// implements `Deref` to `[u8]`. So all methods available on `[u8]`
10 /// are also available on `BStr`.
11 ///
12 /// # Representation
13 ///
14 /// A `&BStr` has the same representation as a `&str`. That is, a `&BStr` is
15 /// a fat pointer which consists of a pointer to some bytes and a length.
16 ///
17 /// # Trait implementations
18 ///
19 /// The `BStr` type has a number of trait implementations, and in particular,
20 /// defines equality and ordinal comparisons between `&BStr`, `&str` and
21 /// `&[u8]` for convenience.
22 ///
23 /// The `Debug` implementation for `BStr` shows its bytes as a normal string.
24 /// For invalid UTF-8, hex escape sequences are used.
25 ///
26 /// The `Display` implementation behaves as if `BStr` were first lossily
27 /// converted to a `str`. Invalid UTF-8 bytes are substituted with the Unicode
28 /// replacement codepoint, which looks like this: �.
29 #[derive(Hash)]
30 #[repr(transparent)]
31 pub struct BStr {
32     pub(crate) bytes: [u8],
33 }
34 
35 impl BStr {
36     #[inline]
new<B: ?Sized + AsRef<[u8]>>(bytes: &B) -> &BStr37     pub(crate) fn new<B: ?Sized + AsRef<[u8]>>(bytes: &B) -> &BStr {
38         BStr::from_bytes(bytes.as_ref())
39     }
40 
41     #[inline]
new_mut<B: ?Sized + AsMut<[u8]>>( bytes: &mut B, ) -> &mut BStr42     pub(crate) fn new_mut<B: ?Sized + AsMut<[u8]>>(
43         bytes: &mut B,
44     ) -> &mut BStr {
45         BStr::from_bytes_mut(bytes.as_mut())
46     }
47 
48     #[inline]
from_bytes(slice: &[u8]) -> &BStr49     pub(crate) fn from_bytes(slice: &[u8]) -> &BStr {
50         unsafe { mem::transmute(slice) }
51     }
52 
53     #[inline]
from_bytes_mut(slice: &mut [u8]) -> &mut BStr54     pub(crate) fn from_bytes_mut(slice: &mut [u8]) -> &mut BStr {
55         unsafe { mem::transmute(slice) }
56     }
57 
58     #[inline]
59     #[cfg(feature = "std")]
from_boxed_bytes(slice: Box<[u8]>) -> Box<BStr>60     pub(crate) fn from_boxed_bytes(slice: Box<[u8]>) -> Box<BStr> {
61         unsafe { Box::from_raw(Box::into_raw(slice) as _) }
62     }
63 
64     #[inline]
65     #[cfg(feature = "std")]
into_boxed_bytes(slice: Box<BStr>) -> Box<[u8]>66     pub(crate) fn into_boxed_bytes(slice: Box<BStr>) -> Box<[u8]> {
67         unsafe { Box::from_raw(Box::into_raw(slice) as _) }
68     }
69 
70     #[inline]
as_bytes(&self) -> &[u8]71     pub(crate) fn as_bytes(&self) -> &[u8] {
72         &self.bytes
73     }
74 }
75