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