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