serde_human_bytes/
bytearray.rs

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