Coverage Report

Created: 2026-06-15 06:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/minicbor-0.18.0/src/bytes.rs
Line
Count
Source
1
//! Newtypes for `&[u8]`, `[u8;N]` and `Vec<u8>`.
2
//!
3
//! To support specialised encoding and decoding of byte slices, byte arrays,
4
//! and vectors which are represented as CBOR bytes instead of arrays of `u8`s,
5
//! the types `ByteSlice`, `ByteArray` and `ByteVec` (requires feature "alloc")
6
//! are provided. These implement [`Encode`] and [`Decode`] by translating to
7
//! and from CBOR bytes.
8
//!
9
//! If the feature "derive" is present, specialised traits `EncodeBytes` and
10
//! `DecodeBytes` are also provided. These are implemented for the
11
//! aforementioned newtypes as well as for their `Option` variations, regular
12
//! `&[u8]`, `[u8; N]`, `Vec<u8>` and for `Cow<'_, [u8]>` if the alloc feature
13
//! is given. They enable the direct use of `&[u8]`, `[u8; N]`, `Vec<u8>` and
14
//! `Cow<'_, [u8]>` in types deriving `Encode` and `Decode` if used with a
15
//! `#[cbor(with = "minicbor::bytes")]` annotation.
16
17
use crate::decode::{self, Decode, Decoder};
18
use crate::encode::{self, Encode, Encoder, Write};
19
use core::ops::{Deref, DerefMut};
20
21
#[cfg(feature = "alloc")]
22
use alloc::vec::Vec;
23
24
#[cfg(all(feature = "alloc", feature = "derive"))]
25
use alloc::borrow::{Cow, ToOwned};
26
27
/// Newtype for `[u8]`.
28
///
29
/// Used to implement `Encode` and `Decode` which translate to
30
/// CBOR bytes instead of arrays for `u8`s.
31
#[repr(transparent)]
32
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Hash)]
33
pub struct ByteSlice([u8]);
34
35
impl<'a> From<&'a [u8]> for &'a ByteSlice {
36
0
    fn from(xs: &'a [u8]) -> Self {
37
        unsafe {
38
0
            &*(xs as *const [u8] as *const ByteSlice)
39
        }
40
0
    }
41
}
42
43
impl<'a> From<&'a mut [u8]> for &'a mut ByteSlice {
44
0
    fn from(xs: &'a mut [u8]) -> Self {
45
0
        unsafe {
46
0
            &mut *(xs as *mut [u8] as *mut ByteSlice)
47
0
        }
48
0
    }
49
}
50
51
impl Deref for ByteSlice {
52
    type Target = [u8];
53
54
0
    fn deref(&self) -> &Self::Target {
55
0
        &self.0
56
0
    }
57
}
58
59
impl DerefMut for ByteSlice {
60
0
    fn deref_mut(&mut self) -> &mut Self::Target {
61
0
        &mut self.0
62
0
    }
63
}
64
65
impl AsRef<[u8]> for ByteSlice {
66
0
    fn as_ref(&self) -> &[u8] {
67
0
        &self.0
68
0
    }
69
}
70
71
impl AsMut<[u8]> for ByteSlice {
72
0
    fn as_mut(&mut self) -> &mut [u8] {
73
0
        &mut self.0
74
0
    }
75
}
76
77
impl<'a, 'b: 'a, C> Decode<'b, C> for &'a ByteSlice {
78
0
    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, decode::Error> {
79
0
        d.bytes().map(<&ByteSlice>::from)
80
0
    }
81
}
82
83
impl<C> Encode<C> for ByteSlice {
84
0
    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), encode::Error<W::Error>> {
85
0
        e.bytes(self)?.ok()
86
0
    }
87
}
88
89
#[cfg(feature = "alloc")]
90
impl core::borrow::Borrow<ByteSlice> for Vec<u8> {
91
0
    fn borrow(&self) -> &ByteSlice {
92
0
        self.as_slice().into()
93
0
    }
94
}
95
96
#[cfg(feature = "alloc")]
97
impl core::borrow::BorrowMut<ByteSlice> for Vec<u8> {
98
0
    fn borrow_mut(&mut self) -> &mut ByteSlice {
99
0
        self.as_mut_slice().into()
100
0
    }
101
}
102
103
#[cfg(feature = "alloc")]
104
impl core::borrow::Borrow<ByteSlice> for ByteVec {
105
0
    fn borrow(&self) -> &ByteSlice {
106
0
        self.as_slice().into()
107
0
    }
108
}
109
110
#[cfg(feature = "alloc")]
111
impl core::borrow::BorrowMut<ByteSlice> for ByteVec {
112
0
    fn borrow_mut(&mut self) -> &mut ByteSlice {
113
0
        self.as_mut_slice().into()
114
0
    }
115
}
116
117
impl<const N: usize> core::borrow::Borrow<ByteSlice> for ByteArray<N> {
118
0
    fn borrow(&self) -> &ByteSlice {
119
0
        self.0[..].into()
120
0
    }
121
}
122
123
impl<const N: usize> core::borrow::BorrowMut<ByteSlice> for ByteArray<N> {
124
0
    fn borrow_mut(&mut self) -> &mut ByteSlice {
125
0
        (&mut self.0[..]).into()
126
0
    }
127
}
128
129
#[cfg(feature = "alloc")]
130
impl alloc::borrow::ToOwned for ByteSlice {
131
    type Owned = ByteVec;
132
133
0
    fn to_owned(&self) -> Self::Owned {
134
0
        ByteVec::from(self.to_vec())
135
0
    }
136
}
137
138
/// Newtype for `[u8; N]`.
139
///
140
/// Used to implement `Encode` and `Decode` which translate to
141
/// CBOR bytes instead of arrays for `u8`s.
142
#[repr(transparent)]
143
#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)]
144
pub struct ByteArray<const N: usize>([u8; N]);
145
146
impl<const N: usize> From<[u8; N]> for ByteArray<N> {
147
0
    fn from(a: [u8; N]) -> Self {
148
0
        ByteArray(a)
149
0
    }
150
}
151
152
impl<const N: usize> From<ByteArray<N>> for [u8; N] {
153
0
    fn from(a: ByteArray<N>) -> Self {
154
0
        a.0
155
0
    }
156
}
157
158
impl<const N: usize> Deref for ByteArray<N> {
159
    type Target = [u8; N];
160
161
0
    fn deref(&self) -> &Self::Target {
162
0
        &self.0
163
0
    }
164
}
165
166
impl<const N: usize> DerefMut for ByteArray<N> {
167
0
    fn deref_mut(&mut self) -> &mut Self::Target {
168
0
        &mut self.0
169
0
    }
170
}
171
172
impl<const N: usize> AsRef<[u8; N]> for ByteArray<N> {
173
0
    fn as_ref(&self) -> &[u8; N] {
174
0
        &self.0
175
0
    }
176
}
177
178
impl<const N: usize> AsMut<[u8; N]> for ByteArray<N> {
179
0
    fn as_mut(&mut self) -> &mut [u8; N] {
180
0
        &mut self.0
181
0
    }
182
}
183
184
impl<'b, C, const N: usize> Decode<'b, C> for ByteArray<N> {
185
0
    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, decode::Error> {
186
0
        let pos   = d.position();
187
0
        let slice = d.bytes()?;
188
0
        let array = <[u8; N]>::try_from(slice).map_err(|_| {
189
0
            decode::Error::message("byte slice length does not match expected array length").at(pos)
190
0
        })?;
191
0
        Ok(ByteArray(array))
192
0
    }
193
}
194
195
impl<C, const N: usize> Encode<C> for ByteArray<N> {
196
0
    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), encode::Error<W::Error>> {
197
0
        e.bytes(&self.0[..])?.ok()
198
0
    }
199
}
200
201
/// Newtype for `Vec<u8>`.
202
///
203
/// Used to implement `Encode` and `Decode` which translate to
204
/// CBOR bytes instead of arrays for `u8`s.
205
#[cfg(feature = "alloc")]
206
#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)]
207
pub struct ByteVec(Vec<u8>);
208
209
#[cfg(feature = "alloc")]
210
impl From<Vec<u8>> for ByteVec {
211
0
    fn from(xs: Vec<u8>) -> Self {
212
0
        ByteVec(xs)
213
0
    }
214
}
215
216
#[cfg(feature = "alloc")]
217
impl From<ByteVec> for Vec<u8> {
218
0
    fn from(b: ByteVec) -> Self {
219
0
        b.0
220
0
    }
221
}
222
223
#[cfg(feature = "alloc")]
224
impl Deref for ByteVec {
225
    type Target = Vec<u8>;
226
227
0
    fn deref(&self) -> &Self::Target {
228
0
        &self.0
229
0
    }
230
}
231
232
#[cfg(feature = "alloc")]
233
impl DerefMut for ByteVec {
234
0
    fn deref_mut(&mut self) -> &mut Self::Target {
235
0
        &mut self.0
236
0
    }
237
}
238
239
#[cfg(feature = "alloc")]
240
impl<C> Decode<'_, C> for ByteVec {
241
0
    fn decode(d: &mut Decoder<'_>, _: &mut C) -> Result<Self, decode::Error> {
242
0
        d.bytes().map(|xs| xs.to_vec().into())
243
0
    }
244
}
245
246
#[cfg(feature = "alloc")]
247
impl<C> Encode<C> for ByteVec {
248
0
    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), encode::Error<W::Error>> {
249
0
        e.bytes(self)?.ok()
250
0
    }
251
}
252
253
// Traits /////////////////////////////////////////////////////////////////////
254
255
/// Like [`Encode`] but specific for encoding of byte slices.
256
#[cfg(feature = "derive")]
257
pub trait EncodeBytes<C> {
258
    fn encode_bytes<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), encode::Error<W::Error>>;
259
260
    fn is_nil(&self) -> bool {
261
        false
262
    }
263
}
264
265
/// Like [`Decode`] but specific for decoding from byte slices.
266
#[cfg(feature = "derive")]
267
pub trait DecodeBytes<'b, C>: Sized {
268
    fn decode_bytes(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, decode::Error>;
269
270
    fn nil() -> Option<Self> {
271
        None
272
    }
273
}
274
275
#[cfg(feature = "derive")]
276
impl<'a, C, T: EncodeBytes<C> + ?Sized> EncodeBytes<C> for &'a T {
277
    fn encode_bytes<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), encode::Error<W::Error>> {
278
        (**self).encode_bytes(e, ctx)
279
    }
280
}
281
282
#[cfg(feature = "derive")]
283
impl<C> EncodeBytes<C> for [u8] {
284
    fn encode_bytes<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), encode::Error<W::Error>> {
285
        e.bytes(self)?.ok()
286
    }
287
}
288
289
#[cfg(feature = "derive")]
290
impl<'a, 'b: 'a, C> DecodeBytes<'b, C> for &'a [u8] {
291
    fn decode_bytes(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, decode::Error> {
292
        d.bytes()
293
    }
294
}
295
296
#[cfg(feature = "derive")]
297
impl<C, const N: usize> EncodeBytes<C> for [u8; N] {
298
    fn encode_bytes<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), encode::Error<W::Error>> {
299
        e.bytes(&self[..])?.ok()
300
    }
301
}
302
303
#[cfg(feature = "derive")]
304
impl<'b, C, const N: usize> DecodeBytes<'b, C> for [u8; N] {
305
    fn decode_bytes(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, decode::Error> {
306
        ByteArray::decode(d, ctx).map(ByteArray::into)
307
    }
308
}
309
310
#[cfg(all(feature = "alloc", feature = "derive"))]
311
impl<C> EncodeBytes<C> for Vec<u8> {
312
    fn encode_bytes<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), encode::Error<W::Error>> {
313
        e.bytes(self.as_slice())?.ok()
314
    }
315
}
316
317
#[cfg(all(feature = "alloc", feature = "derive"))]
318
impl<'b, C> DecodeBytes<'b, C> for Vec<u8> {
319
    fn decode_bytes(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, decode::Error> {
320
        d.bytes().map(Vec::from)
321
    }
322
}
323
324
#[cfg(feature = "derive")]
325
impl<C> EncodeBytes<C> for ByteSlice {
326
    fn encode_bytes<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), encode::Error<W::Error>> {
327
        Self::encode(self, e, ctx)
328
    }
329
}
330
331
#[cfg(feature = "derive")]
332
impl<'a, 'b: 'a, C> DecodeBytes<'b, C> for &'a ByteSlice {
333
    fn decode_bytes(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, decode::Error> {
334
        Self::decode(d, ctx)
335
    }
336
}
337
338
#[cfg(feature = "derive")]
339
impl<C, const N: usize> EncodeBytes<C> for ByteArray<N> {
340
    fn encode_bytes<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), encode::Error<W::Error>> {
341
        Self::encode(self, e, ctx)
342
    }
343
}
344
345
#[cfg(feature = "derive")]
346
impl<'b, C, const N: usize> DecodeBytes<'b, C> for ByteArray<N> {
347
    fn decode_bytes(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, decode::Error> {
348
        Self::decode(d, ctx)
349
    }
350
}
351
352
#[cfg(all(feature = "alloc", feature = "derive"))]
353
impl<C> EncodeBytes<C> for ByteVec {
354
    fn encode_bytes<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), encode::Error<W::Error>> {
355
        Self::encode(self, e, ctx)
356
    }
357
}
358
359
#[cfg(all(feature = "alloc", feature = "derive"))]
360
impl<'b, C> DecodeBytes<'b, C> for ByteVec {
361
    fn decode_bytes(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, decode::Error> {
362
        Self::decode(d, ctx)
363
    }
364
}
365
366
#[cfg(feature = "derive")]
367
impl<C, T: EncodeBytes<C>> EncodeBytes<C> for Option<T> {
368
    fn encode_bytes<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), encode::Error<W::Error>> {
369
        if let Some(x) = self {
370
            x.encode_bytes(e, ctx)
371
        } else {
372
            e.null()?.ok()
373
        }
374
    }
375
376
    fn is_nil(&self) -> bool {
377
        self.is_none()
378
    }
379
}
380
381
#[cfg(feature = "derive")]
382
impl<'b, C, T: DecodeBytes<'b, C>> DecodeBytes<'b, C> for Option<T> {
383
    fn decode_bytes(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, decode::Error> {
384
        if crate::data::Type::Null == d.datatype()? {
385
            d.skip()?;
386
            return Ok(None)
387
        }
388
        T::decode_bytes(d, ctx).map(Some)
389
    }
390
391
    fn nil() -> Option<Self> {
392
        Some(None)
393
    }
394
}
395
396
#[cfg(all(feature = "alloc", feature = "derive"))]
397
impl<C> EncodeBytes<C> for Cow<'_, [u8]> {
398
    fn encode_bytes<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), encode::Error<W::Error>> {
399
        self.as_ref().encode_bytes(e, ctx)
400
    }
401
}
402
403
#[cfg(all(feature = "alloc", feature = "derive"))]
404
impl<'b, C> DecodeBytes<'b, C> for Cow<'_, [u8]> {
405
    fn decode_bytes(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, decode::Error> {
406
        let slice = <&'b ByteSlice>::decode_bytes(d, ctx)?;
407
        Ok(Cow::Owned(slice.to_owned().into()))
408
    }
409
}
410
411
/// Freestanding function calling `DecodeBytes::decode_bytes`.
412
///
413
/// For use in `#[cbor(with = "minicbor::bytes")]` or `#[cbor(decode_with =
414
/// "minicbor::bytes::decode")]`.
415
#[cfg(feature = "derive")]
416
pub fn decode<'b, C, T>(d: &mut Decoder<'b>, ctx: &mut C) -> Result<T, decode::Error>
417
where
418
    T: DecodeBytes<'b, C>
419
{
420
    T::decode_bytes(d, ctx)
421
}
422
423
#[cfg(feature = "derive")]
424
pub fn nil<'b, C, T>() -> Option<T>
425
where
426
    T: DecodeBytes<'b, C>
427
{
428
    T::nil()
429
}
430
431
/// Freestanding function calling `EncodeBytes::encode_bytes`.
432
///
433
/// For use in `#[cbor(with = "minicbor::bytes")]` or `#[cbor(encode_with =
434
/// "minicbor::bytes::encode")]`.
435
#[cfg(feature = "derive")]
436
pub fn encode<C, T, W>(xs: &T, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), encode::Error<W::Error>>
437
where
438
    T: EncodeBytes<C>,
439
    W: Write
440
{
441
    T::encode_bytes(xs, e, ctx)
442
}
443
444
#[cfg(feature = "derive")]
445
pub fn is_nil<C, T>(xs: &T) -> bool
446
where
447
    T: EncodeBytes<C>
448
{
449
    T::is_nil(xs)
450
}