commonware_codec/types/
vec.rs

1//! Codec implementation for [`Vec<T>`].
2//!
3//! For portability and consistency between architectures,
4//! the length of the vector must fit within a [`u32`].
5
6use crate::{Config, EncodeSize, Error, RangeConfig, Read, Write};
7use bytes::{Buf, BufMut};
8
9impl<T: Write> Write for Vec<T> {
10    #[inline]
11    fn write(&self, buf: &mut impl BufMut) {
12        self.len().write(buf);
13        for item in self {
14            item.write(buf);
15        }
16    }
17}
18
19impl<T: EncodeSize> EncodeSize for Vec<T> {
20    #[inline]
21    fn encode_size(&self) -> usize {
22        self.len().encode_size() + self.iter().map(EncodeSize::encode_size).sum::<usize>()
23    }
24}
25
26impl<R: RangeConfig, Cfg: Config, T: Read<Cfg>> Read<(R, Cfg)> for Vec<T> {
27    #[inline]
28    fn read_cfg(buf: &mut impl Buf, (range, cfg): &(R, Cfg)) -> Result<Self, Error> {
29        let len = usize::read_cfg(buf, range)?;
30        let mut vec = Vec::with_capacity(len);
31        for _ in 0..len {
32            vec.push(T::read_cfg(buf, cfg)?);
33        }
34        Ok(vec)
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41    use crate::{DecodeRangeExt, Encode};
42
43    #[test]
44    fn test_vec() {
45        let vec_values = [vec![], vec![1u8], vec![1u8, 2u8, 3u8]];
46        for value in vec_values {
47            let encoded = value.encode();
48            assert_eq!(encoded.len(), value.len() * std::mem::size_of::<u8>() + 1);
49
50            // Valid decoding
51            let len = value.len();
52            let decoded = Vec::<u8>::decode_range(encoded, len..=len).unwrap();
53            assert_eq!(value, decoded);
54
55            // Failure for too long
56            assert!(matches!(
57                Vec::<u8>::decode_range(value.encode(), 0..len),
58                Err(Error::InvalidLength(_))
59            ));
60
61            // Failure for too short
62            assert!(matches!(
63                Vec::<u8>::decode_range(value.encode(), len + 1..),
64                Err(Error::InvalidLength(_))
65            ));
66        }
67    }
68}