octseq/
array.rs

1//! A fixed-capacity octets sequence.
2
3use core::{cmp, fmt};
4use core::ops::RangeBounds;
5use crate::builder::{
6    EmptyBuilder, FreezeBuilder, FromBuilder, IntoBuilder, OctetsBuilder,
7    ShortBuf, Truncate,
8};
9use crate::octets::{Octets, OctetsFrom};
10
11
12//------------ Array ---------------------------------------------------------
13
14#[derive(Clone)]
15pub struct Array<const N: usize> {
16    octets: [u8; N],
17    len: usize
18}
19
20impl<const N: usize> Array<N> {
21    /// Creates a new empty value.
22    pub fn new() -> Self {
23        Default::default()
24    }
25
26    /// Returns an octets slice with the content of the array.
27    pub fn as_slice(&self) -> &[u8] {
28        &self.octets[..self.len]
29    }
30
31    /// Returns a mutable octets slice with the content of the array.
32    pub fn as_slice_mut(&mut self) -> &mut [u8] {
33        &mut self.octets[..self.len]
34    }
35
36    /// Resizes the array in place updating additional octets.
37    ///
38    /// The method only changes the length of the contained octets
39    /// sequence. If `new_len` is greater than the current length, the
40    /// content of the additional octets will be left at whatever they
41    /// were.
42    ///
43    /// Returns an error if `new_len` is larger than the array size.
44    pub fn resize_raw(&mut self, new_len: usize) -> Result<(), ShortBuf> {
45        if new_len >= N {
46            Err(ShortBuf)
47        }
48        else {
49            self.len = new_len;
50            Ok(())
51        }
52    }
53}
54
55
56//--- Default
57
58impl<const N: usize> Default for Array<N> {
59    fn default() -> Self {
60        Array {
61            octets: [0; N],
62            len: 0
63        }
64    }
65}
66
67
68//--- TryFrom
69
70impl<'a, const N: usize> TryFrom<&'a [u8]> for Array<N> {
71    type Error = ShortBuf;
72
73    fn try_from(src: &'a [u8]) -> Result<Self, ShortBuf> {
74        let len = src.len();
75        if len > N {
76            Err(ShortBuf)
77        }
78        else {
79            let mut res = Self::default();
80            res.octets[..len].copy_from_slice(src);
81            res.len = len;
82            Ok(res)
83        }
84    }
85}
86
87
88//--- Deref, AsRef, Borrow, and Mut versions
89
90impl<const N: usize> core::ops::Deref for Array<N> {
91    type Target = [u8];
92
93    fn deref(&self) -> &Self::Target {
94        self.as_slice()
95    }
96}
97
98impl<const N: usize> core::ops::DerefMut for Array<N> {
99    fn deref_mut(&mut self) -> &mut Self::Target {
100        self.as_slice_mut()
101    }
102}
103
104impl<const N: usize> AsRef<[u8]> for Array<N> {
105    fn as_ref(&self) -> &[u8] {
106        self.as_slice()
107    }
108}
109
110impl<const N: usize> AsMut<[u8]> for Array<N> {
111    fn as_mut(&mut self) -> &mut [u8] {
112        self.as_slice_mut()
113    }
114}
115
116impl<const N: usize> core::borrow::Borrow<[u8]> for Array<N> {
117    fn borrow(&self) -> &[u8] {
118        self.as_slice()
119    }
120}
121
122impl<const N: usize> core::borrow::BorrowMut<[u8]> for Array<N> {
123    fn borrow_mut(&mut self) -> &mut [u8] {
124        self.as_slice_mut()
125    }
126}
127
128//--- Truncate
129
130impl<const N: usize> Octets for Array<N> {
131    type Range<'a> = &'a [u8];
132
133    fn range(&self, range: impl RangeBounds<usize>) -> Self::Range<'_> {
134        self.as_slice().range(range)
135    }
136}
137
138
139//--- Truncate
140
141impl<const N: usize> Truncate for Array<N> {
142    fn truncate(&mut self, len: usize) {
143        self.len = cmp::min(self.len, len)
144    }
145}
146
147
148//--- OctetsBuilder, EmptyBuilder, and FreezeBuilder
149
150impl<const N: usize> OctetsBuilder for Array<N> {
151    type AppendError = ShortBuf;
152
153    fn append_slice(
154        &mut self, slice: &[u8]
155    ) -> Result<(), Self::AppendError> {
156        let end = self.len + slice.len();
157        if end > N {
158            return Err(ShortBuf)
159        }
160        self.octets[self.len..end].copy_from_slice(slice);
161        self.len = end;
162        Ok(())
163    }
164}
165
166impl<const N: usize> EmptyBuilder for Array<N> {
167    fn empty() -> Self {
168        Default::default()
169    }
170
171    fn with_capacity(_capacity: usize) -> Self {
172        Self::empty()
173    }
174}
175
176impl<const N: usize> FreezeBuilder for Array<N> {
177    type Octets = Self;
178
179    fn freeze(self) -> Self::Octets {
180        self
181    }
182}
183
184
185//--- IntoBuilder, FromBuilder
186
187impl<const N: usize> IntoBuilder for Array<N> {
188    type Builder = Self;
189
190    fn into_builder(self) -> Self::Builder {
191        self
192    }
193}
194
195impl<const N: usize> FromBuilder for Array<N> {
196    type Builder = Self;
197
198    fn from_builder(builder: Self::Builder) -> Self {
199        builder
200    }
201}
202
203
204//--- OctetsFrom
205
206impl<Source: AsRef<[u8]>, const N: usize> OctetsFrom<Source> for Array<N> {
207    type Error = ShortBuf;
208
209    fn try_octets_from(source: Source) -> Result<Self, Self::Error> {
210        Self::try_from(source.as_ref())
211    }
212}
213
214
215//--- PartialEq and Eq
216
217impl<T: AsRef<[u8]>, const N: usize> PartialEq<T> for Array<N> {
218    fn eq(&self, other: &T) -> bool {
219        self.as_slice().eq(other.as_ref())
220    }
221}
222
223impl<const N: usize> Eq for Array<N> { }
224
225
226//--- PartialOrd and Ord
227
228impl<T: AsRef<[u8]>, const N: usize> PartialOrd<T> for Array<N> {
229    fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
230        self.as_slice().partial_cmp(other.as_ref())
231    }
232}
233
234impl<const N: usize> Ord for Array<N> {
235    fn cmp(&self, other: &Self) -> cmp::Ordering {
236        self.as_slice().cmp(other)
237    }
238}
239
240
241//--- Hash
242
243impl<const N: usize> core::hash::Hash for Array<N> {
244    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
245        self.as_slice().hash(state)
246    }
247}
248
249
250//--- Debug
251
252impl<const N: usize> fmt::Debug for Array<N> {
253    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
254        f.debug_tuple("octets::Array")
255            .field(&self.as_slice())
256            .finish()
257    }
258}
259
260
261//--- SerializeOctets and DeserializeOctets
262
263#[cfg(feature = "serde")]
264impl<const N: usize> crate::serde::SerializeOctets for Array<N> {
265    fn serialize_octets<S: serde::Serializer>(
266        &self, serializer: S
267    ) -> Result<S::Ok, S::Error> {
268        serializer.serialize_bytes(self.as_ref())
269    }
270}
271
272#[cfg(feature = "serde")]
273impl<'de, const N: usize> crate::serde::DeserializeOctets<'de> for Array<N> {
274    type Visitor = ArrayVisitor<N>;
275
276    fn deserialize_octets<D: serde::Deserializer<'de>>(
277        deserializer: D
278    ) -> Result<Self, D::Error> {
279        Self::visitor().deserialize(deserializer)
280    }
281
282    fn deserialize_with_visitor<D, V>(
283        deserializer: D,
284        visitor: V,
285    ) -> Result<V::Value, D::Error>
286    where
287        D: serde::Deserializer<'de>,
288        V: serde::de::Visitor<'de>,
289    {
290        deserializer.deserialize_byte_buf(visitor)
291    }
292
293    fn visitor() -> Self::Visitor {
294        ArrayVisitor
295    }
296}
297
298
299//------------ ArrayVisitor ----------------------------------------------
300
301#[cfg(feature = "serde")]
302pub struct ArrayVisitor<const N: usize>;
303
304#[cfg(feature = "serde")]
305impl<const N: usize> ArrayVisitor<N> {
306    pub fn deserialize<'de, D: serde::Deserializer<'de>>(
307        self,
308        deserializer: D,
309    ) -> Result<Array<N>, D::Error> {
310        deserializer.deserialize_byte_buf(self)
311    }
312}
313
314#[cfg(feature = "serde")]
315impl<'de, const N: usize> serde::de::Visitor<'de> for ArrayVisitor<N> {
316    type Value = Array<N>;
317
318    fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
319        f.write_str("an octet sequence")
320    }
321
322    fn visit_bytes<E: serde::de::Error>(
323        self, value: &[u8]
324    ) -> Result<Self::Value, E> {
325        Array::try_from(value).map_err(E::custom)
326    }
327}
328