Coverage Report

Created: 2026-01-10 06:06

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