1use 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#[derive(Clone)]
15pub struct Array<const N: usize> {
16 octets: [u8; N],
17 len: usize
18}
19
20impl<const N: usize> Array<N> {
21 pub fn new() -> Self {
23 Default::default()
24 }
25
26 pub fn as_slice(&self) -> &[u8] {
28 &self.octets[..self.len]
29 }
30
31 pub fn as_slice_mut(&mut self) -> &mut [u8] {
33 &mut self.octets[..self.len]
34 }
35
36 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
56impl<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
68impl<'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
88impl<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
128impl<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
139impl<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
148impl<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
185impl<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
204impl<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
215impl<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
226impl<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
241impl<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
250impl<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#[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#[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