Skip to main content

postcard_heapless_compat/
lib.rs

1#![no_std]
2
3use heapless::Vec;
4use heapless_vec::HVec;
5use postcard::serialize_with_flavor;
6use postcard::{Error, Result};
7use serde::Serialize;
8
9/// Serialize a `T` to a `heapless::Vec<u8>`, with the `Vec` containing
10/// data in a serialized format.
11///
12pub fn to_vec<T, const B: usize>(value: &T) -> Result<Vec<u8, B>>
13where
14    T: Serialize + ?Sized,
15{
16    serialize_with_flavor::<T, HVec<B>, Vec<u8, B>>(value, HVec::default())
17}
18
19mod heapless_vec {
20    use crate::{Error, Result};
21    use core::ops::Index;
22    use core::ops::IndexMut;
23    use postcard::ser_flavors::Flavor;
24
25    use heapless::Vec;
26
27    ////////////////////////////////////////
28    // HVec
29    ////////////////////////////////////////
30
31    /// The `HVec` flavor is a wrapper type around a `heapless::Vec`. This is a stack
32    /// allocated data structure, with a fixed maximum size and variable amount of contents.
33    #[derive(Default)]
34    pub struct HVec<const B: usize> {
35        /// the contained data buffer
36        vec: Vec<u8, B>,
37    }
38
39    impl<const B: usize> Flavor for HVec<B> {
40        type Output = Vec<u8, B>;
41
42        #[inline(always)]
43        fn try_extend(&mut self, data: &[u8]) -> Result<()> {
44            self.vec
45                .extend_from_slice(data)
46                .map_err(|_| Error::SerializeBufferFull)
47        }
48
49        #[inline(always)]
50        fn try_push(&mut self, data: u8) -> Result<()> {
51            self.vec.push(data).map_err(|_| Error::SerializeBufferFull)
52        }
53
54        fn finalize(self) -> Result<Vec<u8, B>> {
55            Ok(self.vec)
56        }
57    }
58
59    impl<const B: usize> Index<usize> for HVec<B> {
60        type Output = u8;
61
62        fn index(&self, idx: usize) -> &u8 {
63            &self.vec[idx]
64        }
65    }
66
67    impl<const B: usize> IndexMut<usize> for HVec<B> {
68        fn index_mut(&mut self, idx: usize) -> &mut u8 {
69            &mut self.vec[idx]
70        }
71    }
72}