Skip to main content

serde_bytes/
bytearray.rs

1use core::{
2    borrow::{Borrow, BorrowMut},
3    cmp::Ordering,
4    fmt::{self, Debug},
5    hash::{Hash, Hasher},
6    ops::{Deref, DerefMut},
7    ptr,
8};
9
10use serde::{
11    de::{Deserialize, Deserializer, Error, SeqAccess, Visitor},
12    ser::{Serialize, Serializer},
13};
14
15use crate::Bytes;
16
17/// Wrapper around `[u8; N]` to serialize and deserialize efficiently.
18///
19/// ```
20/// use std::collections::HashMap;
21///
22/// use serde_bytes::ByteArray;
23///
24/// fn deserialize_bytearrays() -> serde_json::Result<()> {
25///     let example_data = br#"{"1":[111,110,101],"2":[116,119,111]}"#;
26///
27///     let map: HashMap<u32, ByteArray<3>> = serde_json::from_slice(example_data)?;
28///
29///     println!("{:?}", map);
30///
31///     Ok(())
32/// }
33/// #
34/// # fn main() {
35/// #     deserialize_bytearrays().unwrap();
36/// # }
37/// ```
38#[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    /// Wrap an existing [array] into a `ByteArray`.
46    pub const fn new(bytes: [u8; N]) -> Self {
47        ByteArray {
48            bytes,
49        }
50    }
51
52    /// Unwrap the byte array underlying this `ByteArray`.
53    pub const fn into_array(self) -> [u8; N] {
54        self.bytes
55    }
56
57    fn from_ref(bytes: &[u8; N]) -> &Self {
58        unsafe { &*ptr::addr_of!(*bytes).cast::<ByteArray<N>>() }
59    }
60}
61
62impl<const N: usize> Debug for ByteArray<N> {
63    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64        Debug::fmt(&self.bytes, f)
65    }
66}
67
68impl<const N: usize> Default for ByteArray<N> {
69    fn default() -> Self {
70        ByteArray {
71            bytes: [0; N],
72        }
73    }
74}
75
76impl<const N: usize> AsRef<[u8; N]> for ByteArray<N> {
77    fn as_ref(&self) -> &[u8; N] {
78        &self.bytes
79    }
80}
81
82impl<const N: usize> AsMut<[u8; N]> for ByteArray<N> {
83    fn as_mut(&mut self) -> &mut [u8; N] {
84        &mut self.bytes
85    }
86}
87
88impl<const N: usize> Borrow<[u8; N]> for ByteArray<N> {
89    fn borrow(&self) -> &[u8; N] {
90        &self.bytes
91    }
92}
93
94impl<const N: usize> BorrowMut<[u8; N]> for ByteArray<N> {
95    fn borrow_mut(&mut self) -> &mut [u8; N] {
96        &mut self.bytes
97    }
98}
99
100impl<const N: usize> Deref for ByteArray<N> {
101    type Target = [u8; N];
102
103    fn deref(&self) -> &Self::Target {
104        &self.bytes
105    }
106}
107
108impl<const N: usize> DerefMut for ByteArray<N> {
109    fn deref_mut(&mut self) -> &mut Self::Target {
110        &mut self.bytes
111    }
112}
113
114impl<const N: usize> Borrow<Bytes> for ByteArray<N> {
115    fn borrow(&self) -> &Bytes {
116        Bytes::new(&self.bytes)
117    }
118}
119
120impl<const N: usize> BorrowMut<Bytes> for ByteArray<N> {
121    fn borrow_mut(&mut self) -> &mut Bytes {
122        unsafe { &mut *(&mut self.bytes as &mut [u8] as *mut [u8] as *mut Bytes) }
123    }
124}
125
126impl<const N: usize> From<[u8; N]> for ByteArray<N> {
127    fn from(bytes: [u8; N]) -> Self {
128        ByteArray {
129            bytes,
130        }
131    }
132}
133
134impl<Rhs, const N: usize> PartialEq<Rhs> for ByteArray<N>
135where
136    Rhs: ?Sized + Borrow<[u8; N]>,
137{
138    fn eq(&self, other: &Rhs) -> bool {
139        self.as_ref().eq(other.borrow())
140    }
141}
142
143impl<Rhs, const N: usize> PartialOrd<Rhs> for ByteArray<N>
144where
145    Rhs: ?Sized + Borrow<[u8; N]>,
146{
147    fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> {
148        self.as_ref().partial_cmp(other.borrow())
149    }
150}
151
152impl<const N: usize> Hash for ByteArray<N> {
153    fn hash<H: Hasher>(&self, state: &mut H) {
154        self.bytes.hash(state);
155    }
156}
157
158impl<const N: usize> IntoIterator for ByteArray<N> {
159    type Item = u8;
160    type IntoIter = <[u8; N] as IntoIterator>::IntoIter;
161
162    fn into_iter(self) -> Self::IntoIter {
163        IntoIterator::into_iter(self.bytes)
164    }
165}
166
167impl<'a, const N: usize> IntoIterator for &'a ByteArray<N> {
168    type Item = &'a u8;
169    type IntoIter = <&'a [u8; N] as IntoIterator>::IntoIter;
170
171    fn into_iter(self) -> Self::IntoIter {
172        self.bytes.iter()
173    }
174}
175
176impl<'a, const N: usize> IntoIterator for &'a mut ByteArray<N> {
177    type Item = &'a mut u8;
178    type IntoIter = <&'a mut [u8; N] as IntoIterator>::IntoIter;
179
180    fn into_iter(self) -> Self::IntoIter {
181        self.bytes.iter_mut()
182    }
183}
184
185impl<const N: usize> Serialize for ByteArray<N> {
186    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
187    where
188        S: Serializer,
189    {
190        serializer.serialize_bytes(&self.bytes)
191    }
192}
193
194struct ByteArrayVisitor<const N: usize>;
195
196impl<'de, const N: usize> Visitor<'de> for ByteArrayVisitor<N> {
197    type Value = ByteArray<N>;
198
199    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
200        write!(formatter, "a byte array of length {N}")
201    }
202
203    fn visit_seq<V>(self, mut seq: V) -> Result<ByteArray<N>, V::Error>
204    where
205        V: SeqAccess<'de>,
206    {
207        let mut bytes = [0; N];
208
209        for (idx, byte) in bytes.iter_mut().enumerate() {
210            *byte = seq
211                .next_element()?
212                .ok_or_else(|| V::Error::invalid_length(idx, &self))?;
213        }
214
215        Ok(ByteArray::new(bytes))
216    }
217
218    fn visit_bytes<E>(self, v: &[u8]) -> Result<ByteArray<N>, E>
219    where
220        E: Error,
221    {
222        Ok(ByteArray {
223            bytes: v.try_into().map_err(|_| E::invalid_length(v.len(), &self))?,
224        })
225    }
226
227    fn visit_str<E>(self, v: &str) -> Result<ByteArray<N>, E>
228    where
229        E: Error,
230    {
231        self.visit_bytes(v.as_bytes())
232    }
233}
234
235impl<'de, const N: usize> Deserialize<'de> for ByteArray<N> {
236    fn deserialize<D>(deserializer: D) -> Result<ByteArray<N>, D::Error>
237    where
238        D: Deserializer<'de>,
239    {
240        deserializer.deserialize_bytes(ByteArrayVisitor::<N>)
241    }
242}
243
244struct BorrowedByteArrayVisitor<const N: usize>;
245
246impl<'de, const N: usize> Visitor<'de> for BorrowedByteArrayVisitor<N> {
247    type Value = &'de ByteArray<N>;
248
249    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
250        write!(formatter, "a borrowed byte array of length {N}")
251    }
252
253    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
254    where
255        E: Error,
256    {
257        let borrowed_byte_array: &'de [u8; N] = v.try_into().map_err(|_| E::invalid_length(v.len(), &self))?;
258        Ok(ByteArray::from_ref(borrowed_byte_array))
259    }
260
261    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
262    where
263        E: Error,
264    {
265        self.visit_borrowed_bytes(v.as_bytes())
266    }
267}
268
269impl<'a, 'de: 'a, const N: usize> Deserialize<'de> for &'a ByteArray<N> {
270    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
271    where
272        D: Deserializer<'de>,
273    {
274        deserializer.deserialize_bytes(BorrowedByteArrayVisitor::<N>)
275    }
276}