postcard/de/
mod.rs

1use cobs::{decode_in_place, decode_in_place_report};
2use serde::Deserialize;
3
4pub(crate) mod deserializer;
5pub mod flavors;
6
7use crate::error::{Error, Result};
8use deserializer::Deserializer;
9
10/// Deserialize a message of type `T` from a byte slice. The unused portion (if any)
11/// of the byte slice is not returned.
12pub fn from_bytes<'a, T>(s: &'a [u8]) -> Result<T>
13where
14    T: Deserialize<'a>,
15{
16    let mut deserializer = Deserializer::from_bytes(s);
17    let t = T::deserialize(&mut deserializer)?;
18    Ok(t)
19}
20
21/// Deserialize a message of type `T` from a cobs-encoded byte slice.
22///
23/// The unused portion (if any) of the byte slice is not returned.
24/// The used portion of the input slice is modified during deserialization (even if an error is returned).
25/// Therefore, if this is not desired, pass a clone of the original slice.
26pub fn from_bytes_cobs<'a, T>(s: &'a mut [u8]) -> Result<T>
27where
28    T: Deserialize<'a>,
29{
30    let sz = decode_in_place(s).map_err(|_| Error::DeserializeBadEncoding)?;
31    from_bytes::<T>(&s[..sz])
32}
33
34/// Deserialize a message of type `T` from a cobs-encoded byte slice.
35///
36/// The unused portion (if any) of the byte slice is returned for further usage.
37/// The used portion of the input slice is modified during deserialization (even if an error is returned).
38/// Therefore, if this is not desired, pass a clone of the original slice.
39pub fn take_from_bytes_cobs<'a, T>(s: &'a mut [u8]) -> Result<(T, &'a mut [u8])>
40where
41    T: Deserialize<'a>,
42{
43    let mut report = decode_in_place_report(s).map_err(|_| Error::DeserializeBadEncoding)?;
44
45    // The report does not include terminator bytes. If there is one in the
46    // buffer right AFTER the message, also include it.
47    if s.get(report.src_used) == Some(&0) {
48        report.src_used += 1;
49    }
50
51    // First split off the amount used for the "destination", which includes our now
52    // decoded message to deserialize
53    let (dst_used, dst_unused) = s.split_at_mut(report.dst_used);
54
55    // Then create a slice that includes the unused bytes, but DON'T include the
56    // excess bytes that were "shrunk" away from the original message
57    let (_unused, src_unused) = dst_unused.split_at_mut(report.src_used - report.dst_used);
58    Ok((from_bytes::<T>(dst_used)?, src_unused))
59}
60
61/// Deserialize a message of type `T` from a byte slice. The unused portion (if any)
62/// of the byte slice is returned for further usage
63pub fn take_from_bytes<'a, T>(s: &'a [u8]) -> Result<(T, &'a [u8])>
64where
65    T: Deserialize<'a>,
66{
67    let mut deserializer = Deserializer::from_bytes(s);
68    let t = T::deserialize(&mut deserializer)?;
69    Ok((t, deserializer.finalize()?))
70}
71
72/// Deserialize a message of type `T` from a [`embedded_io`](crate::eio::embedded_io)::[`Read`](crate::eio::Read).
73#[cfg(any(feature = "embedded-io-04", feature = "embedded-io-06"))]
74pub fn from_eio<'a, T, R>(val: (R, &'a mut [u8])) -> Result<(T, (R, &'a mut [u8]))>
75where
76    T: Deserialize<'a>,
77    R: crate::eio::Read + 'a,
78{
79    let flavor = flavors::io::eio::EIOReader::new(val.0, val.1);
80    let mut deserializer = Deserializer::from_flavor(flavor);
81    let t = T::deserialize(&mut deserializer)?;
82    Ok((t, deserializer.finalize()?))
83}
84
85/// Deserialize a message of type `T` from a [`std::io::Read`].
86#[cfg(feature = "use-std")]
87pub fn from_io<'a, T, R>(val: (R, &'a mut [u8])) -> Result<(T, (R, &'a mut [u8]))>
88where
89    T: Deserialize<'a>,
90    R: std::io::Read + 'a,
91{
92    let flavor = flavors::io::io::IOReader::new(val.0, val.1);
93    let mut deserializer = Deserializer::from_flavor(flavor);
94    let t = T::deserialize(&mut deserializer)?;
95    Ok((t, deserializer.finalize()?))
96}
97
98/// Conveniently deserialize a message of type `T` from a byte slice with a Crc. The unused portion (if any)
99/// of the byte slice is not returned.
100///
101/// See the `de_flavors::crc` module for the complete set of functions.
102#[cfg(feature = "use-crc")]
103#[cfg_attr(docsrs, doc(cfg(feature = "use-crc")))]
104#[inline]
105pub fn from_bytes_crc32<'a, T>(s: &'a [u8], digest: crc::Digest<'a, u32>) -> Result<T>
106where
107    T: Deserialize<'a>,
108{
109    flavors::crc::from_bytes_u32(s, digest)
110}
111
112/// Conveniently deserialize a message of type `T` from a byte slice with a Crc. The unused portion (if any)
113/// of the byte slice is returned for further usage
114///
115/// See the `de_flavors::crc` module for the complete set of functions.
116#[cfg(feature = "use-crc")]
117#[cfg_attr(docsrs, doc(cfg(feature = "use-crc")))]
118#[inline]
119pub fn take_from_bytes_crc32<'a, T>(
120    s: &'a [u8],
121    digest: crc::Digest<'a, u32>,
122) -> Result<(T, &'a [u8])>
123where
124    T: Deserialize<'a>,
125{
126    flavors::crc::take_from_bytes_u32(s, digest)
127}
128
129////////////////////////////////////////////////////////////////////////////////
130
131#[cfg(feature = "heapless")]
132#[cfg(test)]
133mod test_heapless {
134    use super::*;
135    use crate::{ser::to_vec, to_vec_cobs, varint::varint_max};
136    use core::fmt::Write;
137    use core::ops::Deref;
138    use heapless::{FnvIndexMap, String, Vec};
139    use serde::{Deserialize, Deserializer, Serialize, Serializer};
140
141    #[test]
142    fn de_u8() {
143        let output: Vec<u8, 1> = to_vec(&0x05u8).unwrap();
144        assert_eq!(&[5], output.deref());
145
146        let out: u8 = from_bytes(output.deref()).unwrap();
147        assert_eq!(out, 0x05);
148    }
149
150    #[test]
151    fn de_u16() {
152        let output: Vec<u8, { varint_max::<u16>() }> = to_vec(&0xA5C7u16).unwrap();
153        assert_eq!(&[0xC7, 0xCB, 0x02], output.deref());
154
155        let out: u16 = from_bytes(output.deref()).unwrap();
156        assert_eq!(out, 0xA5C7);
157    }
158
159    #[test]
160    fn de_u32() {
161        let output: Vec<u8, { varint_max::<u32>() }> = to_vec(&0xCDAB3412u32).unwrap();
162        assert_eq!(&[0x92, 0xE8, 0xAC, 0xED, 0x0C], output.deref());
163
164        let out: u32 = from_bytes(output.deref()).unwrap();
165        assert_eq!(out, 0xCDAB3412u32);
166    }
167
168    #[test]
169    fn de_u64() {
170        let output: Vec<u8, { varint_max::<u64>() }> = to_vec(&0x1234_5678_90AB_CDEFu64).unwrap();
171        assert_eq!(
172            &[0xEF, 0x9B, 0xAF, 0x85, 0x89, 0xCF, 0x95, 0x9A, 0x12],
173            output.deref()
174        );
175
176        let out: u64 = from_bytes(output.deref()).unwrap();
177        assert_eq!(out, 0x1234_5678_90AB_CDEFu64);
178    }
179
180    #[test]
181    fn de_u128() {
182        let output: Vec<u8, { varint_max::<u128>() }> =
183            to_vec(&0x1234_5678_90AB_CDEF_1234_5678_90AB_CDEFu128).unwrap();
184        assert_eq!(
185            &[
186                0xEF, 0x9B, 0xAF, 0x85, 0x89, 0xCF, 0x95, 0x9A, 0x92, 0xDE, 0xB7, 0xDE, 0x8A, 0x92,
187                0x9E, 0xAB, 0xB4, 0x24,
188            ],
189            output.deref()
190        );
191
192        let out: u128 = from_bytes(output.deref()).unwrap();
193        assert_eq!(out, 0x1234_5678_90AB_CDEF_1234_5678_90AB_CDEFu128);
194    }
195
196    #[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
197    struct BasicU8S {
198        st: u16,
199        ei: u8,
200        ote: u128,
201        sf: u64,
202        tt: u32,
203    }
204
205    #[test]
206    fn de_struct_unsigned() {
207        let data = BasicU8S {
208            st: 0xABCD,
209            ei: 0xFE,
210            ote: 0x1234_4321_ABCD_DCBA_1234_4321_ABCD_DCBA,
211            sf: 0x1234_4321_ABCD_DCBA,
212            tt: 0xACAC_ACAC,
213        };
214
215        const SZ: usize = varint_max::<u16>()
216            + 1
217            + varint_max::<u128>()
218            + varint_max::<u64>()
219            + varint_max::<u32>();
220
221        let output: Vec<u8, SZ> = to_vec(&data).unwrap();
222
223        assert_eq!(
224            &[
225                0xCD, 0xD7, 0x02, 0xFE, 0xBA, 0xB9, 0xB7, 0xDE, 0x9A, 0xE4, 0x90, 0x9A, 0x92, 0xF4,
226                0xF2, 0xEE, 0xBC, 0xB5, 0xC8, 0xA1, 0xB4, 0x24, 0xBA, 0xB9, 0xB7, 0xDE, 0x9A, 0xE4,
227                0x90, 0x9A, 0x12, 0xAC, 0xD9, 0xB2, 0xE5, 0x0A
228            ],
229            output.deref()
230        );
231
232        let out: BasicU8S = from_bytes(output.deref()).unwrap();
233        assert_eq!(out, data);
234    }
235
236    #[test]
237    fn de_byte_slice() {
238        let input: &[u8] = &[1u8, 2, 3, 4, 5, 6, 7, 8];
239        let output: Vec<u8, 9> = to_vec(input).unwrap();
240        assert_eq!(
241            &[0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08],
242            output.deref()
243        );
244
245        let out: Vec<u8, 128> = from_bytes(output.deref()).unwrap();
246        assert_eq!(input, out.deref());
247
248        let mut input: Vec<u8, 1024> = Vec::new();
249        for i in 0..1024 {
250            input.push((i & 0xFF) as u8).unwrap();
251        }
252        let output: Vec<u8, 2048> = to_vec(input.deref()).unwrap();
253        assert_eq!(&[0x80, 0x08], &output.deref()[..2]);
254
255        assert_eq!(output.len(), 1026);
256        for (i, val) in output.deref()[2..].iter().enumerate() {
257            assert_eq!((i & 0xFF) as u8, *val);
258        }
259
260        let de: Vec<u8, 1024> = from_bytes(output.deref()).unwrap();
261        assert_eq!(input.deref(), de.deref());
262    }
263
264    #[test]
265    fn de_str() {
266        let input: &str = "hello, postcard!";
267        let output: Vec<u8, 17> = to_vec(input).unwrap();
268        assert_eq!(0x10, output.deref()[0]);
269        assert_eq!(input.as_bytes(), &output.deref()[1..]);
270
271        let mut input: String<1024> = String::new();
272        for _ in 0..256 {
273            write!(&mut input, "abcd").unwrap();
274        }
275        let output: Vec<u8, 2048> = to_vec(input.deref()).unwrap();
276        assert_eq!(&[0x80, 0x08], &output.deref()[..2]);
277
278        assert_eq!(output.len(), 1026);
279        for ch in output.deref()[2..].chunks(4) {
280            assert_eq!("abcd", core::str::from_utf8(ch).unwrap());
281        }
282
283        let de: String<1024> = from_bytes(output.deref()).unwrap();
284        assert_eq!(input.deref(), de.deref());
285    }
286
287    #[allow(dead_code)]
288    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
289    enum BasicEnum {
290        Bib,
291        Bim,
292        Bap,
293    }
294
295    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
296    struct EnumStruct {
297        eight: u8,
298        sixt: u16,
299    }
300
301    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
302    enum DataEnum {
303        Bib(u16),
304        Bim(u64),
305        Bap(u8),
306        Kim(EnumStruct),
307        Chi { a: u8, b: u32 },
308        Sho(u16, u8),
309    }
310
311    #[test]
312    fn enums() {
313        let output: Vec<u8, 1> = to_vec(&BasicEnum::Bim).unwrap();
314        assert_eq!(&[0x01], output.deref());
315        let out: BasicEnum = from_bytes(output.deref()).unwrap();
316        assert_eq!(out, BasicEnum::Bim);
317
318        let output: Vec<u8, { 1 + varint_max::<u64>() }> =
319            to_vec(&DataEnum::Bim(u64::MAX)).unwrap();
320        assert_eq!(
321            &[0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01],
322            output.deref()
323        );
324
325        let output: Vec<u8, { 1 + varint_max::<u16>() }> =
326            to_vec(&DataEnum::Bib(u16::MAX)).unwrap();
327        assert_eq!(&[0x00, 0xFF, 0xFF, 0x03], output.deref());
328        let out: DataEnum = from_bytes(output.deref()).unwrap();
329        assert_eq!(out, DataEnum::Bib(u16::MAX));
330
331        let output: Vec<u8, 2> = to_vec(&DataEnum::Bap(u8::MAX)).unwrap();
332        assert_eq!(&[0x02, 0xFF], output.deref());
333        let out: DataEnum = from_bytes(output.deref()).unwrap();
334        assert_eq!(out, DataEnum::Bap(u8::MAX));
335
336        let output: Vec<u8, 8> = to_vec(&DataEnum::Kim(EnumStruct {
337            eight: 0xF0,
338            sixt: 0xACAC,
339        }))
340        .unwrap();
341        assert_eq!(&[0x03, 0xF0, 0xAC, 0xD9, 0x02], output.deref());
342        let out: DataEnum = from_bytes(output.deref()).unwrap();
343        assert_eq!(
344            out,
345            DataEnum::Kim(EnumStruct {
346                eight: 0xF0,
347                sixt: 0xACAC
348            })
349        );
350
351        let output: Vec<u8, 8> = to_vec(&DataEnum::Chi {
352            a: 0x0F,
353            b: 0xC7C7C7C7,
354        })
355        .unwrap();
356        assert_eq!(&[0x04, 0x0F, 0xC7, 0x8F, 0x9F, 0xBE, 0x0C], output.deref());
357        let out: DataEnum = from_bytes(output.deref()).unwrap();
358        assert_eq!(
359            out,
360            DataEnum::Chi {
361                a: 0x0F,
362                b: 0xC7C7C7C7
363            }
364        );
365
366        let output: Vec<u8, 8> = to_vec(&DataEnum::Sho(0x6969, 0x07)).unwrap();
367        assert_eq!(&[0x05, 0xE9, 0xD2, 0x01, 0x07], output.deref());
368        let out: DataEnum = from_bytes(output.deref()).unwrap();
369        assert_eq!(out, DataEnum::Sho(0x6969, 0x07));
370    }
371
372    #[test]
373    fn tuples() {
374        let output: Vec<u8, 128> = to_vec(&(1u8, 10u32, "Hello!")).unwrap();
375        assert_eq!(
376            &[1u8, 0x0A, 0x06, b'H', b'e', b'l', b'l', b'o', b'!'],
377            output.deref()
378        );
379        let out: (u8, u32, &str) = from_bytes(output.deref()).unwrap();
380        assert_eq!(out, (1u8, 10u32, "Hello!"));
381    }
382
383    #[derive(Debug, Eq, PartialEq)]
384    pub struct ByteSliceStruct<'a> {
385        bytes: &'a [u8],
386    }
387
388    impl Serialize for ByteSliceStruct<'_> {
389        fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
390        where
391            S: Serializer,
392        {
393            // Serialization is generic for all slice types, so the default serialization of byte
394            // slices does not use `Serializer::serialize_bytes`.
395            serializer.serialize_bytes(self.bytes)
396        }
397    }
398
399    impl<'a, 'de> Deserialize<'de> for ByteSliceStruct<'a>
400    where
401        'de: 'a,
402    {
403        fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
404        where
405            D: Deserializer<'de>,
406        {
407            // Deserialization of byte slices is specialized for byte slices, so the default
408            // deserialization will call `Deserializer::deserialize_bytes`.
409            Ok(Self {
410                bytes: Deserialize::deserialize(deserializer)?,
411            })
412        }
413    }
414
415    #[test]
416    fn bytes() {
417        let x: &[u8; 32] = &[0u8; 32];
418        let output: Vec<u8, 128> = to_vec(x).unwrap();
419        assert_eq!(output.len(), 32);
420        let out: [u8; 32] = from_bytes(output.deref()).unwrap();
421        assert_eq!(out, [0u8; 32]);
422
423        let x: &[u8] = &[0u8; 32];
424        let output: Vec<u8, 128> = to_vec(x).unwrap();
425        assert_eq!(output.len(), 33);
426        let out: &[u8] = from_bytes(output.deref()).unwrap();
427        assert_eq!(out, [0u8; 32]);
428
429        let x = ByteSliceStruct { bytes: &[0u8; 32] };
430        let output: Vec<u8, 128> = to_vec(&x).unwrap();
431        assert_eq!(output.len(), 33);
432        let out: ByteSliceStruct<'_> = from_bytes(output.deref()).unwrap();
433        assert_eq!(out, ByteSliceStruct { bytes: &[0u8; 32] });
434    }
435
436    #[test]
437    fn chars() {
438        let x: char = 'a';
439        let output: Vec<u8, 5> = to_vec(&x).unwrap();
440        assert_eq!(output.len(), 2);
441        let out: char = from_bytes(output.deref()).unwrap();
442        assert_eq!(out, 'a');
443    }
444
445    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
446    pub struct NewTypeStruct(u32);
447
448    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
449    pub struct TupleStruct((u8, u16));
450
451    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
452    pub struct DualTupleStruct(u8, u16);
453
454    #[test]
455    fn structs() {
456        let output: Vec<u8, 4> = to_vec(&NewTypeStruct(5)).unwrap();
457        assert_eq!(&[0x05], output.deref());
458        let out: NewTypeStruct = from_bytes(output.deref()).unwrap();
459        assert_eq!(out, NewTypeStruct(5));
460
461        let output: Vec<u8, 3> = to_vec(&TupleStruct((0xA0, 0x1234))).unwrap();
462        assert_eq!(&[0xA0, 0xB4, 0x24], output.deref());
463        let out: TupleStruct = from_bytes(output.deref()).unwrap();
464        assert_eq!(out, TupleStruct((0xA0, 0x1234)));
465
466        let output: Vec<u8, 3> = to_vec(&DualTupleStruct(0xA0, 0x1234)).unwrap();
467        assert_eq!(&[0xA0, 0xB4, 0x24], output.deref());
468        let out: DualTupleStruct = from_bytes(output.deref()).unwrap();
469        assert_eq!(out, DualTupleStruct(0xA0, 0x1234));
470    }
471
472    #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
473    struct RefStruct<'a> {
474        bytes: &'a [u8],
475        str_s: &'a str,
476    }
477
478    #[test]
479    fn ref_struct() {
480        let message = "hElLo";
481        let bytes = [0x01, 0x10, 0x02, 0x20];
482        let output: Vec<u8, 11> = to_vec(&RefStruct {
483            bytes: &bytes,
484            str_s: message,
485        })
486        .unwrap();
487
488        assert_eq!(
489            &[0x04, 0x01, 0x10, 0x02, 0x20, 0x05, b'h', b'E', b'l', b'L', b'o',],
490            output.deref()
491        );
492
493        let out: RefStruct<'_> = from_bytes(output.deref()).unwrap();
494        assert_eq!(
495            out,
496            RefStruct {
497                bytes: &bytes,
498                str_s: message,
499            }
500        );
501    }
502
503    #[test]
504    fn unit() {
505        let output: Vec<u8, 1> = to_vec(&()).unwrap();
506        assert_eq!(output.len(), 0);
507        let _: () = from_bytes(output.deref()).unwrap();
508    }
509
510    #[test]
511    fn heapless_data() {
512        let mut input: Vec<u8, 4> = Vec::new();
513        input.extend_from_slice(&[0x01, 0x02, 0x03, 0x04]).unwrap();
514        let output: Vec<u8, 5> = to_vec(&input).unwrap();
515        assert_eq!(&[0x04, 0x01, 0x02, 0x03, 0x04], output.deref());
516        let out: Vec<u8, 4> = from_bytes(output.deref()).unwrap();
517        assert_eq!(out, input);
518
519        let mut input: String<8> = String::new();
520        write!(&mut input, "helLO!").unwrap();
521        let output: Vec<u8, 7> = to_vec(&input).unwrap();
522        assert_eq!(&[0x06, b'h', b'e', b'l', b'L', b'O', b'!'], output.deref());
523        let out: String<8> = from_bytes(output.deref()).unwrap();
524        assert_eq!(input, out);
525
526        let mut input: FnvIndexMap<u8, u8, 4> = FnvIndexMap::new();
527        input.insert(0x01, 0x05).unwrap();
528        input.insert(0x02, 0x06).unwrap();
529        input.insert(0x03, 0x07).unwrap();
530        input.insert(0x04, 0x08).unwrap();
531        let output: Vec<u8, 100> = to_vec(&input).unwrap();
532        assert_eq!(
533            &[0x04, 0x01, 0x05, 0x02, 0x06, 0x03, 0x07, 0x04, 0x08],
534            output.deref()
535        );
536        let out: FnvIndexMap<u8, u8, 4> = from_bytes(output.deref()).unwrap();
537        assert_eq!(input, out);
538    }
539
540    #[test]
541    fn cobs_test() {
542        let message = "hElLo";
543        let bytes = [0x01, 0x00, 0x02, 0x20];
544        let input = RefStruct {
545            bytes: &bytes,
546            str_s: message,
547        };
548
549        let output: Vec<u8, 11> = to_vec(&input).unwrap();
550
551        let mut encode_buf = [0u8; 32];
552        let sz = cobs::encode(output.deref(), &mut encode_buf);
553        let out = from_bytes_cobs::<RefStruct<'_>>(&mut encode_buf[..sz]).unwrap();
554
555        assert_eq!(input, out);
556    }
557
558    #[test]
559    fn take_from_includes_terminator() {
560        // With the null terminator
561        let mut output: Vec<u8, 32> = to_vec_cobs(&(4i32, 0u8, 4u64)).unwrap();
562        let (val, remain) = take_from_bytes_cobs::<(i32, u8, u64)>(&mut output).unwrap();
563        assert_eq!((4, 0, 4), val);
564        assert_eq!(remain.len(), 0);
565
566        // without the null terminator
567        let mut output: Vec<u8, 32> = to_vec_cobs(&(4i32, 0u8, 4u64)).unwrap();
568        assert_eq!(output.pop(), Some(0));
569        let (val, remain) = take_from_bytes_cobs::<(i32, u8, u64)>(&mut output).unwrap();
570        assert_eq!((4, 0, 4), val);
571        assert_eq!(remain.len(), 0);
572    }
573}
574
575#[cfg(any(feature = "alloc", feature = "use-std"))]
576#[cfg(test)]
577mod test_alloc {
578    extern crate alloc;
579
580    use super::*;
581
582    use alloc::vec;
583    use serde::Deserialize;
584
585    #[derive(Debug, Deserialize, PartialEq)]
586    struct ZSTStruct;
587
588    #[test]
589    fn zst_vec() {
590        assert_eq!(from_bytes(&[3]), Ok(vec![ZSTStruct, ZSTStruct, ZSTStruct]));
591
592        assert_eq!(
593            from_bytes(&[4]),
594            Ok(vec![ZSTStruct, ZSTStruct, ZSTStruct, ZSTStruct])
595        );
596    }
597
598    #[test]
599    fn vec() {
600        assert_eq!(
601            from_bytes::<Vec<u8>>(&[8, 255, 255, 255, 0, 0, 0, 0, 0]),
602            Ok(vec![255, 255, 255, 0, 0, 0, 0, 0])
603        );
604
605        // This won't actually prove anything since tests will likely always be
606        // run on devices with larger amounts of memory, but it can't hurt.
607        assert_eq!(
608            from_bytes::<Vec<u8>>(&[(1 << 7) | 8, 255, 255, 255, 0, 0, 0, 0, 0]),
609            Err(Error::DeserializeUnexpectedEnd)
610        );
611    }
612}