1 //! Common handling for types backed by byte slices with enforcement of a
2 //! library-level length limitation i.e. `Length::max()`.
3 
4 use crate::{
5     DecodeValue, DerOrd, EncodeValue, Error, Header, Length, Reader, Result, StrRef, Writer,
6 };
7 use core::cmp::Ordering;
8 
9 #[cfg(feature = "alloc")]
10 use crate::StrOwned;
11 
12 /// Byte slice newtype which respects the `Length::max()` limit.
13 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
14 pub(crate) struct BytesRef<'a> {
15     /// Precomputed `Length` (avoids possible panicking conversions)
16     pub length: Length,
17 
18     /// Inner value
19     pub inner: &'a [u8],
20 }
21 
22 impl<'a> BytesRef<'a> {
23     /// Constant value representing an empty byte slice.
24     pub const EMPTY: Self = Self {
25         length: Length::ZERO,
26         inner: &[],
27     };
28 
29     /// Create a new [`BytesRef`], ensuring that the provided `slice` value
30     /// is shorter than `Length::max()`.
new(slice: &'a [u8]) -> Result<Self>31     pub fn new(slice: &'a [u8]) -> Result<Self> {
32         Ok(Self {
33             length: Length::try_from(slice.len())?,
34             inner: slice,
35         })
36     }
37 
38     /// Borrow the inner byte slice
as_slice(&self) -> &'a [u8]39     pub fn as_slice(&self) -> &'a [u8] {
40         self.inner
41     }
42 
43     /// Get the [`Length`] of this [`BytesRef`]
len(self) -> Length44     pub fn len(self) -> Length {
45         self.length
46     }
47 
48     /// Is this [`BytesRef`] empty?
is_empty(self) -> bool49     pub fn is_empty(self) -> bool {
50         self.len() == Length::ZERO
51     }
52 }
53 
54 impl AsRef<[u8]> for BytesRef<'_> {
as_ref(&self) -> &[u8]55     fn as_ref(&self) -> &[u8] {
56         self.as_slice()
57     }
58 }
59 
60 impl<'a> DecodeValue<'a> for BytesRef<'a> {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>61     fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
62         reader.read_slice(header.length).and_then(Self::new)
63     }
64 }
65 
66 impl EncodeValue for BytesRef<'_> {
value_len(&self) -> Result<Length>67     fn value_len(&self) -> Result<Length> {
68         Ok(self.length)
69     }
70 
encode_value(&self, writer: &mut impl Writer) -> Result<()>71     fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
72         writer.write(self.as_ref())
73     }
74 }
75 
76 impl Default for BytesRef<'_> {
default() -> Self77     fn default() -> Self {
78         Self {
79             length: Length::ZERO,
80             inner: &[],
81         }
82     }
83 }
84 
85 impl DerOrd for BytesRef<'_> {
der_cmp(&self, other: &Self) -> Result<Ordering>86     fn der_cmp(&self, other: &Self) -> Result<Ordering> {
87         Ok(self.as_slice().cmp(other.as_slice()))
88     }
89 }
90 
91 impl<'a> From<StrRef<'a>> for BytesRef<'a> {
from(s: StrRef<'a>) -> BytesRef<'a>92     fn from(s: StrRef<'a>) -> BytesRef<'a> {
93         let bytes = s.as_bytes();
94         debug_assert_eq!(bytes.len(), usize::try_from(s.length).expect("overflow"));
95 
96         BytesRef {
97             inner: bytes,
98             length: s.length,
99         }
100     }
101 }
102 
103 #[cfg(feature = "alloc")]
104 impl<'a> From<&'a StrOwned> for BytesRef<'a> {
from(s: &'a StrOwned) -> BytesRef<'a>105     fn from(s: &'a StrOwned) -> BytesRef<'a> {
106         let bytes = s.as_bytes();
107         debug_assert_eq!(bytes.len(), usize::try_from(s.length).expect("overflow"));
108 
109         BytesRef {
110             inner: bytes,
111             length: s.length,
112         }
113     }
114 }
115 
116 impl<'a> TryFrom<&'a [u8]> for BytesRef<'a> {
117     type Error = Error;
118 
try_from(slice: &'a [u8]) -> Result<Self>119     fn try_from(slice: &'a [u8]) -> Result<Self> {
120         Self::new(slice)
121     }
122 }
123 
124 // Implement by hand because the derive would create invalid values.
125 // Make sure the length and the inner.len matches.
126 #[cfg(feature = "arbitrary")]
127 impl<'a> arbitrary::Arbitrary<'a> for BytesRef<'a> {
arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self>128     fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
129         let length = u.arbitrary()?;
130         Ok(Self {
131             length,
132             inner: u.bytes(u32::from(length) as usize)?,
133         })
134     }
135 
size_hint(depth: usize) -> (usize, Option<usize>)136     fn size_hint(depth: usize) -> (usize, Option<usize>) {
137         arbitrary::size_hint::and(Length::size_hint(depth), (0, None))
138     }
139 }
140 
141 #[cfg(feature = "alloc")]
142 mod allocating {
143     use super::BytesRef;
144     use crate::{referenced::RefToOwned, BytesOwned};
145 
146     impl<'a> RefToOwned<'a> for BytesRef<'a> {
147         type Owned = BytesOwned;
ref_to_owned(&self) -> Self::Owned148         fn ref_to_owned(&self) -> Self::Owned {
149             BytesOwned::from(*self)
150         }
151     }
152 }
153