serde_human_bytes/
bytearray.rs1use 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#[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 pub const fn new(bytes: [u8; N]) -> Self {
48 ByteArray { bytes }
49 }
50
51 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}