• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::Bytes;
2 use core::borrow::{Borrow, BorrowMut};
3 use core::cmp::Ordering;
4 use core::convert::TryInto as _;
5 use core::fmt::{self, Debug};
6 use core::hash::{Hash, Hasher};
7 use core::ops::{Deref, DerefMut};
8 
9 use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor};
10 use 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)]
40 pub struct ByteArray<const N: usize> {
41     bytes: [u8; N],
42 }
43 
44 impl<const N: usize> ByteArray<N> {
45     /// Wrap an existing [array] into a `ByteArray`.
new(bytes: [u8; N]) -> Self46     pub const fn new(bytes: [u8; N]) -> Self {
47         ByteArray { bytes }
48     }
49 
50     /// Unwrap the byte array underlying this `ByteArray`.
into_array(self) -> [u8; N]51     pub const fn into_array(self) -> [u8; N] {
52         self.bytes
53     }
54 
from_ref(bytes: &[u8; N]) -> &Self55     fn from_ref(bytes: &[u8; N]) -> &Self {
56         unsafe { &*(bytes as *const [u8; N] as *const ByteArray<N>) }
57     }
58 }
59 
60 impl<const N: usize> Debug for ByteArray<N> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result61     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
62         Debug::fmt(&self.bytes, f)
63     }
64 }
65 
66 impl<const N: usize> Default for ByteArray<N> {
default() -> Self67     fn default() -> Self {
68         ByteArray { bytes: [0; N] }
69     }
70 }
71 
72 impl<const N: usize> AsRef<[u8; N]> for ByteArray<N> {
as_ref(&self) -> &[u8; N]73     fn as_ref(&self) -> &[u8; N] {
74         &self.bytes
75     }
76 }
77 
78 impl<const N: usize> AsMut<[u8; N]> for ByteArray<N> {
as_mut(&mut self) -> &mut [u8; N]79     fn as_mut(&mut self) -> &mut [u8; N] {
80         &mut self.bytes
81     }
82 }
83 
84 impl<const N: usize> Borrow<[u8; N]> for ByteArray<N> {
borrow(&self) -> &[u8; N]85     fn borrow(&self) -> &[u8; N] {
86         &self.bytes
87     }
88 }
89 
90 impl<const N: usize> BorrowMut<[u8; N]> for ByteArray<N> {
borrow_mut(&mut self) -> &mut [u8; N]91     fn borrow_mut(&mut self) -> &mut [u8; N] {
92         &mut self.bytes
93     }
94 }
95 
96 impl<const N: usize> Deref for ByteArray<N> {
97     type Target = [u8; N];
98 
deref(&self) -> &Self::Target99     fn deref(&self) -> &Self::Target {
100         &self.bytes
101     }
102 }
103 
104 impl<const N: usize> DerefMut for ByteArray<N> {
deref_mut(&mut self) -> &mut Self::Target105     fn deref_mut(&mut self) -> &mut Self::Target {
106         &mut self.bytes
107     }
108 }
109 
110 impl<const N: usize> Borrow<Bytes> for ByteArray<N> {
borrow(&self) -> &Bytes111     fn borrow(&self) -> &Bytes {
112         Bytes::new(&self.bytes)
113     }
114 }
115 
116 impl<const N: usize> BorrowMut<Bytes> for ByteArray<N> {
borrow_mut(&mut self) -> &mut Bytes117     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 
122 impl<const N: usize> From<[u8; N]> for ByteArray<N> {
from(bytes: [u8; N]) -> Self123     fn from(bytes: [u8; N]) -> Self {
124         ByteArray { bytes }
125     }
126 }
127 
128 impl<Rhs, const N: usize> PartialEq<Rhs> for ByteArray<N>
129 where
130     Rhs: ?Sized + Borrow<[u8; N]>,
131 {
eq(&self, other: &Rhs) -> bool132     fn eq(&self, other: &Rhs) -> bool {
133         self.as_ref().eq(other.borrow())
134     }
135 }
136 
137 impl<Rhs, const N: usize> PartialOrd<Rhs> for ByteArray<N>
138 where
139     Rhs: ?Sized + Borrow<[u8; N]>,
140 {
partial_cmp(&self, other: &Rhs) -> Option<Ordering>141     fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> {
142         self.as_ref().partial_cmp(other.borrow())
143     }
144 }
145 
146 impl<const N: usize> Hash for ByteArray<N> {
hash<H: Hasher>(&self, state: &mut H)147     fn hash<H: Hasher>(&self, state: &mut H) {
148         self.bytes.hash(state);
149     }
150 }
151 
152 impl<const N: usize> IntoIterator for ByteArray<N> {
153     type Item = u8;
154     type IntoIter = <[u8; N] as IntoIterator>::IntoIter;
155 
into_iter(self) -> Self::IntoIter156     fn into_iter(self) -> Self::IntoIter {
157         IntoIterator::into_iter(self.bytes)
158     }
159 }
160 
161 impl<'a, const N: usize> IntoIterator for &'a ByteArray<N> {
162     type Item = &'a u8;
163     type IntoIter = <&'a [u8; N] as IntoIterator>::IntoIter;
164 
into_iter(self) -> Self::IntoIter165     fn into_iter(self) -> Self::IntoIter {
166         self.bytes.iter()
167     }
168 }
169 
170 impl<'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 
into_iter(self) -> Self::IntoIter174     fn into_iter(self) -> Self::IntoIter {
175         self.bytes.iter_mut()
176     }
177 }
178 
179 impl<const N: usize> Serialize for ByteArray<N> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,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 
188 struct ByteArrayVisitor<const N: usize>;
189 
190 impl<'de, const N: usize> Visitor<'de> for ByteArrayVisitor<N> {
191     type Value = ByteArray<N>;
192 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result193     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
194         write!(formatter, "a byte array of length {N}")
195     }
196 
visit_seq<V>(self, mut seq: V) -> Result<ByteArray<N>, V::Error> where V: SeqAccess<'de>,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 
visit_bytes<E>(self, v: &[u8]) -> Result<ByteArray<N>, E> where E: Error,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 
visit_str<E>(self, v: &str) -> Result<ByteArray<N>, E> where E: Error,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 
231 impl<'de, const N: usize> Deserialize<'de> for ByteArray<N> {
deserialize<D>(deserializer: D) -> Result<ByteArray<N>, D::Error> where D: Deserializer<'de>,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 
240 struct BorrowedByteArrayVisitor<const N: usize>;
241 
242 impl<'de, const N: usize> Visitor<'de> for BorrowedByteArrayVisitor<N> {
243     type Value = &'de ByteArray<N>;
244 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result245     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
246         write!(formatter, "a borrowed byte array of length {N}")
247     }
248 
visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E> where E: Error,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 
visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E> where E: Error,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 
267 impl<'a, 'de: 'a, const N: usize> Deserialize<'de> for &'a ByteArray<N> {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,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 }
275