serde_bytes/
bytearray.rs

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