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