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