serde_byte_array/
bytearray.rs1use core::array::TryFromSliceError;
2use core::borrow::{Borrow, BorrowMut};
3use core::cmp::Ordering;
4use core::convert::TryInto;
5use core::fmt::{self, Debug};
6use core::hash::{Hash, Hasher};
7use core::mem;
8use core::ops::{Deref, DerefMut};
9
10use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor};
11use serde::ser::{Serialize, Serializer};
12
13#[derive(Copy, Clone, Eq, Ord)]
39#[repr(transparent)]
40pub struct ByteArray<const N: usize> {
41 bytes: [u8; N],
42}
43
44impl<const N: usize> ByteArray<N> {
45 pub const fn new(bytes: [u8; N]) -> Self {
47 Self { bytes }
48 }
49
50 pub fn from<T: Into<[u8; N]>>(bytes: T) -> Self {
52 Self {
53 bytes: bytes.into(),
54 }
55 }
56
57 pub const fn as_slice(&self) -> &[u8] {
59 &self.bytes
60 }
61
62 pub const fn into_array(self) -> [u8; N] {
64 self.bytes
65 }
66}
67
68impl<const N: usize> From<[u8; N]> for ByteArray<N> {
69 fn from(bytes: [u8; N]) -> ByteArray<N> {
70 ByteArray { bytes }
71 }
72}
73
74impl<const N: usize> From<ByteArray<N>> for [u8; N] {
75 fn from(bytes: ByteArray<N>) -> [u8; N] {
76 bytes.bytes
77 }
78}
79
80impl<'a, const N: usize> From<&'a [u8; N]> for &'a ByteArray<N> {
81 fn from(bytes: &'a [u8; N]) -> &'a ByteArray<N> {
82 unsafe { mem::transmute::<&'a [u8; N], &'a ByteArray<N>>(bytes) }
84 }
85}
86
87impl<'a, const N: usize> From<&'a ByteArray<N>> for &'a [u8; N] {
88 fn from(bytes: &'a ByteArray<N>) -> &'a [u8; N] {
89 unsafe { mem::transmute::<&'a ByteArray<N>, &'a [u8; N]>(bytes) }
91 }
92}
93
94impl<'a, const N: usize> TryFrom<&'a [u8]> for ByteArray<N> {
95 type Error = TryFromSliceError;
96 fn try_from(bytes: &'a [u8]) -> Result<Self, TryFromSliceError> {
97 Ok(Self {
98 bytes: bytes.try_into()?,
99 })
100 }
101}
102
103impl<'a, const N: usize> TryFrom<&'a [u8]> for &'a ByteArray<N> {
104 type Error = TryFromSliceError;
105 fn try_from(bytes: &'a [u8]) -> Result<Self, TryFromSliceError> {
106 let tmp: &'a [u8; N] = bytes.try_into()?;
107 Ok(tmp.into())
108 }
109}
110
111impl<const N: usize> Debug for ByteArray<N> {
112 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113 Debug::fmt(&self.bytes, f)
114 }
115}
116
117impl<const N: usize> Default for ByteArray<N> {
118 fn default() -> Self {
119 Self::new([Default::default(); N])
120 }
121}
122
123impl<const N: usize> AsRef<[u8; N]> for ByteArray<N> {
124 fn as_ref(&self) -> &[u8; N] {
125 &self.bytes
126 }
127}
128impl<const N: usize> AsMut<[u8; N]> for ByteArray<N> {
129 fn as_mut(&mut self) -> &mut [u8; N] {
130 &mut self.bytes
131 }
132}
133
134impl<const N: usize> AsRef<[u8]> for ByteArray<N> {
135 fn as_ref(&self) -> &[u8] {
136 &self.bytes
137 }
138}
139
140impl<const N: usize> AsMut<[u8]> for ByteArray<N> {
141 fn as_mut(&mut self) -> &mut [u8] {
142 &mut self.bytes
143 }
144}
145
146impl<const N: usize> Borrow<[u8; N]> for ByteArray<N> {
147 fn borrow(&self) -> &[u8; N] {
148 &self.bytes
149 }
150}
151impl<const N: usize> BorrowMut<[u8; N]> for ByteArray<N> {
152 fn borrow_mut(&mut self) -> &mut [u8; N] {
153 &mut self.bytes
154 }
155}
156
157impl<const N: usize> Borrow<[u8]> for ByteArray<N> {
158 fn borrow(&self) -> &[u8] {
159 &self.bytes
160 }
161}
162impl<const N: usize> BorrowMut<[u8]> for ByteArray<N> {
163 fn borrow_mut(&mut self) -> &mut [u8] {
164 &mut self.bytes
165 }
166}
167
168impl<const N: usize> Deref for ByteArray<N> {
169 type Target = [u8; N];
170
171 fn deref(&self) -> &Self::Target {
172 &self.bytes
173 }
174}
175
176impl<const N: usize> DerefMut for ByteArray<N> {
177 fn deref_mut(&mut self) -> &mut Self::Target {
178 &mut self.bytes
179 }
180}
181
182impl<Rhs, const N: usize> PartialEq<Rhs> for ByteArray<N>
183where
184 Rhs: ?Sized + Borrow<[u8; N]>,
185{
186 fn eq(&self, other: &Rhs) -> bool {
187 (**self).eq(other.borrow())
188 }
189}
190
191impl<Rhs, const N: usize> PartialOrd<Rhs> for ByteArray<N>
192where
193 Rhs: ?Sized + Borrow<[u8; N]>,
194{
195 fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> {
196 (**self).partial_cmp(other.borrow())
197 }
198}
199
200impl<const N: usize> Hash for ByteArray<N> {
201 fn hash<H: Hasher>(&self, state: &mut H) {
202 self.bytes.hash(state);
203 }
204}
205
206impl<const N: usize> IntoIterator for ByteArray<N> {
207 type Item = u8;
208 type IntoIter = <[u8; N] as IntoIterator>::IntoIter;
209
210 fn into_iter(self) -> Self::IntoIter {
211 IntoIterator::into_iter(self.bytes)
212 }
213}
214
215impl<'a, const N: usize> IntoIterator for &'a ByteArray<N> {
216 type Item = &'a u8;
217 type IntoIter = <&'a [u8; N] as IntoIterator>::IntoIter;
218
219 fn into_iter(self) -> Self::IntoIter {
220 self.bytes.iter()
221 }
222}
223
224impl<'a, const N: usize> IntoIterator for &'a mut ByteArray<N> {
225 type Item = &'a mut u8;
226 type IntoIter = <&'a mut [u8; N] as IntoIterator>::IntoIter;
227
228 fn into_iter(self) -> Self::IntoIter {
229 self.bytes.iter_mut()
230 }
231}
232
233impl<const N: usize> Serialize for ByteArray<N> {
234 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
235 where
236 S: Serializer,
237 {
238 serializer.serialize_bytes(&self.bytes)
239 }
240}
241
242struct ByteArrayVisitor<const N: usize>;
243
244impl<'de, const N: usize> Visitor<'de> for ByteArrayVisitor<N> {
245 type Value = ByteArray<N>;
246
247 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
248 write!(formatter, "a byte array of length {}", N)
249 }
250
251 fn visit_seq<V>(self, mut seq: V) -> Result<ByteArray<N>, V::Error>
252 where
253 V: SeqAccess<'de>,
254 {
255 let mut bytes = [0; N];
256
257 for (idx, byte) in bytes.iter_mut().enumerate() {
258 *byte = seq
259 .next_element()?
260 .ok_or_else(|| V::Error::invalid_length(idx, &self))?;
261 }
262
263 Ok(ByteArray::from(bytes))
264 }
265
266 fn visit_bytes<E>(self, v: &[u8]) -> Result<ByteArray<N>, E>
267 where
268 E: Error,
269 {
270 Ok(ByteArray {
271 bytes: v
272 .try_into()
273 .map_err(|_| E::invalid_length(v.len(), &self))?,
274 })
275 }
276
277 fn visit_str<E>(self, v: &str) -> Result<ByteArray<N>, E>
278 where
279 E: Error,
280 {
281 self.visit_bytes(v.as_bytes())
282 }
283}
284
285impl<'de, const N: usize> Deserialize<'de> for ByteArray<N> {
286 fn deserialize<D>(deserializer: D) -> Result<ByteArray<N>, D::Error>
287 where
288 D: Deserializer<'de>,
289 {
290 deserializer.deserialize_bytes(ByteArrayVisitor::<N>)
291 }
292}
293
294struct ByteArrayRefVisitor<const N: usize>;
295
296impl<'de, const N: usize> Visitor<'de> for ByteArrayRefVisitor<N> {
297 type Value = &'de ByteArray<N>;
298
299 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
300 write!(formatter, "a byte array of length {}", N)
301 }
302
303 fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<&'de ByteArray<N>, E>
304 where
305 E: Error,
306 {
307 let arr: &[u8; N] = v
308 .try_into()
309 .map_err(|_| E::invalid_length(v.len(), &self))?;
310 Ok(arr.into())
311 }
312
313 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<&'de ByteArray<N>, E>
314 where
315 E: Error,
316 {
317 self.visit_borrowed_bytes(v.as_bytes())
318 }
319}
320
321impl<'de, const N: usize> Deserialize<'de> for &'de ByteArray<N> {
322 fn deserialize<D>(deserializer: D) -> Result<&'de ByteArray<N>, D::Error>
323 where
324 D: Deserializer<'de>,
325 {
326 deserializer.deserialize_bytes(ByteArrayRefVisitor)
327 }
328}