Skip to main content

bincake_core/
sized_vec.rs

1//! Defines wrapper types for vectors with sizes of various encodings.
2//!
3//! These types implement the `Serialize` trait, allowing them to be serialized to and deserialized
4//! to a byte buffer with the appropriate size prefix.
5//!
6//! They also dereference to `Vec<T>` for ease of use.
7
8use pastey::paste;
9use taped::Tape;
10
11use crate::{
12    Serialize,
13    error::{DecodeError, EncodeError},
14    read_write::{Read, Write},
15    write_le_num,
16};
17
18/// Initializes a vector with an 8-bit size.
19#[macro_export]
20macro_rules! vec8 {
21    () => { $crate::Vec8::from(vec![]) };
22    ($($x:expr),+ $(,)?) => { $crate::Vec8::from(vec![$($x),+]) };
23    ($x:expr; $n:expr) => { $crate::Vec8::from(vec![$x; $n]) };
24}
25
26/// Initializes a vector with an 16-bit size.
27#[macro_export]
28macro_rules! vec16 {
29    () => { $crate::Vec16::from(vec![]) };
30    ($($x:expr),+ $(,)?) => { $crate::Vec16::from(vec![$($x),+]) };
31    ($x:expr; $n:expr) => { $crate::Vec16::from(vec![$x; $n]) };
32}
33
34/// Initializes a vector with an 32-bit size.
35#[macro_export]
36macro_rules! vec32 {
37    () => { $crate::Vec32::from(vec![]) };
38    ($($x:expr),+ $(,)?) => { $crate::Vec32::from(vec![$($x),+]) };
39    ($x:expr; $n:expr) => { $crate::Vec32::from(vec![$x; $n]) };
40}
41
42/// Initializes a vector with an 64-bit size.
43#[macro_export]
44macro_rules! vec64 {
45    () => { $crate::Vec64::from(vec![]) };
46    ($($x:expr),+ $(,)?) => { $crate::Vec64::from(vec![$($x),+]) };
47    ($x:expr; $n:expr) => { $crate::Vec64::from(vec![$x; $n]) };
48}
49
50/// Initializes a vector with an 128-bit size.
51#[macro_export]
52macro_rules! vec128 {
53    () => { $crate::Vec128::from(vec![]) };
54    ($($x:expr),+ $(,)?) => { $crate::Vec128::from(vec![$($x),+]) };
55    ($x:expr; $n:expr) => { $crate::Vec128::from(vec![$x; $n]) };
56}
57
58/// Implements Serialize for vecs with sizes of various encodings.
59macro_rules! impl_vec_n {
60    ($($width:literal),* $(,)?) => { paste! { $(
61        #[derive(Debug, Clone, PartialEq, Eq)]
62        pub struct [<Vec $width>]<T>(Vec<T>);
63
64        impl<T> [<Vec $width>]<T> {
65            /// Consumes self and returns the inner Vec.
66            pub fn into_inner(self) -> Vec<T> {
67                self.0
68            }
69        }
70
71        // From/Into conversions
72        impl<T> From<Vec<T>> for [<Vec $width>]<T> {
73            fn from(v: Vec<T>) -> Self {
74                Self(v)
75            }
76        }
77
78        impl<T> From<[<Vec $width>]<T>> for Vec<T> {
79            fn from(v: [<Vec $width>]<T>) -> Self {
80                v.0
81            }
82        }
83
84        impl<T: Serialize> Serialize for [<Vec $width>]<T> {
85            fn encode(&self, dest: &mut Vec<u8>) -> Result<(), EncodeError> {
86                let len = self.len();
87                #[cfg(target_pointer_width = "64")]
88                if len > 0xFFFFFFFFusize {
89                    return Err(EncodeError::LengthExceedsPrefix { prefix_size: $width, len })
90                }
91                write_le_num!([<u $width>]; dest, len);
92                for d in self.iter() {
93                    dest.write(d)?;
94                }
95                Ok(())
96            }
97
98            fn decode(src: &mut Tape<'_, u8>) -> Result<Self, DecodeError> {
99                let len = src.read::<[<u $width>]>()? as usize;
100                let mut data = Vec::with_capacity(len);
101                for _ in 0..len {
102                    data.push(src.read::<T>()?);
103                }
104                Ok(Self(data))
105            }
106        }
107
108        impl<T> std::ops::Deref for [<Vec $width>]<T> {
109            type Target = Vec<T>;
110
111            fn deref(&self) -> &Self::Target {
112                &self.0
113            }
114        }
115
116        impl<T> std::ops::DerefMut for [<Vec $width>]<T> {
117            fn deref_mut(&mut self) -> &mut Self::Target {
118                &mut self.0
119            }
120        }
121    )*}};
122}
123
124impl_vec_n!(8, 16, 32, 64, 128);