Skip to main content

platform_serialization/enc/
mod.rs

1use bincode::enc::Encoder;
2use bincode::error::EncodeError;
3use bincode::{enc, Encode};
4use platform_version::version::PlatformVersion;
5
6mod impls;
7
8#[derive(Default)]
9pub(crate) struct VecWriter {
10    inner: Vec<u8>,
11}
12
13impl VecWriter {
14    /// Create a new vec writer with the given capacity
15    #[allow(dead_code)]
16    #[deprecated(note = "This function is marked as unused.")]
17    #[allow(deprecated)]
18    pub fn with_capacity(cap: usize) -> Self {
19        Self {
20            inner: Vec::with_capacity(cap),
21        }
22    }
23    // May not be used in all feature combinations
24    #[allow(dead_code)]
25    #[deprecated(note = "This function is marked as unused.")]
26    #[allow(deprecated)]
27    pub(crate) fn collect(self) -> Vec<u8> {
28        self.inner
29    }
30}
31
32impl enc::write::Writer for VecWriter {
33    #[inline(always)]
34    fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
35        self.inner.extend_from_slice(bytes);
36        Ok(())
37    }
38}
39
40pub trait PlatformVersionEncode {
41    /// Encode a given type.
42    fn platform_encode<E: Encoder>(
43        &self,
44        encoder: &mut E,
45        platform_version: &PlatformVersion,
46    ) -> Result<(), EncodeError>;
47}
48
49/// Encode the variant of the given option. Will not encode the option itself.
50#[inline]
51pub(crate) fn encode_option_variant<E: Encoder, T>(
52    encoder: &mut E,
53    value: &Option<T>,
54) -> Result<(), EncodeError> {
55    match value {
56        None => 0u8.encode(encoder),
57        Some(_) => 1u8.encode(encoder),
58    }
59}
60
61/// Encodes the length of any slice, container, etc into the given encoder
62#[inline]
63pub(crate) fn encode_slice_len<E: Encoder>(encoder: &mut E, len: usize) -> Result<(), EncodeError> {
64    (len as u64).encode(encoder)
65}
66
67#[cfg(test)]
68#[allow(clippy::drop_non_drop)]
69mod tests {
70    use super::*;
71    use bincode::config;
72
73    fn cfg() -> impl bincode::config::Config {
74        config::standard().with_big_endian().with_no_limit()
75    }
76
77    #[test]
78    fn encode_option_variant_none() {
79        let value: Option<u32> = None;
80        let mut writer = VecWriter::default();
81        let mut encoder = bincode::enc::EncoderImpl::new(&mut writer, cfg());
82        encode_option_variant(&mut encoder, &value).unwrap();
83        drop(encoder);
84        assert_eq!(writer.inner, &[0u8]);
85    }
86
87    #[test]
88    fn encode_option_variant_some() {
89        let value: Option<u32> = Some(42);
90        let mut writer = VecWriter::default();
91        let mut encoder = bincode::enc::EncoderImpl::new(&mut writer, cfg());
92        encode_option_variant(&mut encoder, &value).unwrap();
93        drop(encoder);
94        assert_eq!(writer.inner, &[1u8]);
95    }
96
97    #[test]
98    fn encode_slice_len_encodes_as_u64() {
99        let mut writer = VecWriter::default();
100        let mut encoder = bincode::enc::EncoderImpl::new(&mut writer, cfg());
101        encode_slice_len(&mut encoder, 5).unwrap();
102        drop(encoder);
103        // 5 as u64 in big-endian varint
104        let expected = bincode::encode_to_vec(5u64, cfg()).unwrap();
105        assert_eq!(writer.inner, expected);
106    }
107
108    #[test]
109    fn vec_writer_write_impl() {
110        let mut writer = VecWriter::default();
111        bincode::enc::write::Writer::write(&mut writer, b"hello").unwrap();
112        bincode::enc::write::Writer::write(&mut writer, b" world").unwrap();
113        assert_eq!(writer.inner, b"hello world");
114    }
115}