der/
byte_slice.rs

1//! Common handling for types backed by byte slices with enforcement of a
2//! library-level length limitation i.e. `Length::max()`.
3
4use crate::{
5    str_slice::StrSlice, DecodeValue, DerOrd, EncodeValue, Error, Header, Length, Reader, Result,
6    Writer,
7};
8use core::cmp::Ordering;
9
10/// Byte slice newtype which respects the `Length::max()` limit.
11#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
12pub(crate) struct ByteSlice<'a> {
13    /// Precomputed `Length` (avoids possible panicking conversions)
14    length: Length,
15
16    /// Inner value
17    inner: &'a [u8],
18}
19
20impl<'a> ByteSlice<'a> {
21    /// Constant value representing an empty byte slice.
22    pub const EMPTY: Self = Self {
23        length: Length::ZERO,
24        inner: &[],
25    };
26
27    /// Create a new [`ByteSlice`], ensuring that the provided `slice` value
28    /// is shorter than `Length::max()`.
29    pub fn new(slice: &'a [u8]) -> Result<Self> {
30        Ok(Self {
31            length: Length::try_from(slice.len())?,
32            inner: slice,
33        })
34    }
35
36    /// Borrow the inner byte slice
37    pub fn as_slice(&self) -> &'a [u8] {
38        self.inner
39    }
40
41    /// Get the [`Length`] of this [`ByteSlice`]
42    pub fn len(self) -> Length {
43        self.length
44    }
45
46    /// Is this [`ByteSlice`] empty?
47    pub fn is_empty(self) -> bool {
48        self.len() == Length::ZERO
49    }
50}
51
52impl AsRef<[u8]> for ByteSlice<'_> {
53    fn as_ref(&self) -> &[u8] {
54        self.as_slice()
55    }
56}
57
58impl<'a> DecodeValue<'a> for ByteSlice<'a> {
59    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
60        reader.read_slice(header.length).and_then(Self::new)
61    }
62}
63
64impl EncodeValue for ByteSlice<'_> {
65    fn value_len(&self) -> Result<Length> {
66        Ok(self.length)
67    }
68
69    fn encode_value(&self, writer: &mut dyn Writer) -> Result<()> {
70        writer.write(self.as_ref())
71    }
72}
73
74impl Default for ByteSlice<'_> {
75    fn default() -> Self {
76        Self {
77            length: Length::ZERO,
78            inner: &[],
79        }
80    }
81}
82
83impl DerOrd for ByteSlice<'_> {
84    fn der_cmp(&self, other: &Self) -> Result<Ordering> {
85        Ok(self.as_slice().cmp(other.as_slice()))
86    }
87}
88
89impl<'a> From<&'a [u8; 1]> for ByteSlice<'a> {
90    fn from(byte: &'a [u8; 1]) -> ByteSlice<'a> {
91        Self {
92            length: Length::ONE,
93            inner: byte,
94        }
95    }
96}
97
98impl<'a> From<StrSlice<'a>> for ByteSlice<'a> {
99    fn from(s: StrSlice<'a>) -> ByteSlice<'a> {
100        let bytes = s.as_bytes();
101        debug_assert_eq!(bytes.len(), usize::try_from(s.length).expect("overflow"));
102
103        ByteSlice {
104            inner: bytes,
105            length: s.length,
106        }
107    }
108}
109
110impl<'a> TryFrom<&'a [u8]> for ByteSlice<'a> {
111    type Error = Error;
112
113    fn try_from(slice: &'a [u8]) -> Result<Self> {
114        Self::new(slice)
115    }
116}