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::{EncodeSize, Error, RangeCfg, 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<T: Read> Read for Vec<T> {
27    type Cfg = (RangeCfg, T::Cfg);
28
29    #[inline]
30    fn read_cfg(buf: &mut impl Buf, (range, cfg): &Self::Cfg) -> Result<Self, Error> {
31        let len = usize::read_cfg(buf, range)?;
32        let mut vec = Vec::with_capacity(len);
33        for _ in 0..len {
34            vec.push(T::read_cfg(buf, cfg)?);
35        }
36        Ok(vec)
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43    use crate::{DecodeRangeExt, Encode};
44
45    #[test]
46    fn test_vec() {
47        let vec_values = [vec![], vec![1u8], vec![1u8, 2u8, 3u8]];
48        for value in vec_values {
49            let encoded = value.encode();
50            assert_eq!(encoded.len(), value.len() * std::mem::size_of::<u8>() + 1);
51
52            // Valid decoding
53            let len = value.len();
54            let decoded = Vec::<u8>::decode_range(encoded, len..=len).unwrap();
55            assert_eq!(value, decoded);
56
57            // Failure for too long
58            assert!(matches!(
59                Vec::<u8>::decode_range(value.encode(), 0..len),
60                Err(Error::InvalidLength(_))
61            ));
62
63            // Failure for too short
64            assert!(matches!(
65                Vec::<u8>::decode_range(value.encode(), len + 1..),
66                Err(Error::InvalidLength(_))
67            ));
68        }
69    }
70
71    #[test]
72    fn test_conformity() {
73        assert_eq!(Vec::<u8>::new().encode(), &[0x00][..]);
74        assert_eq!(
75            vec![0x01u8, 0x02u8, 0x03u8].encode(),
76            &[0x03, 0x01, 0x02, 0x03][..]
77        );
78
79        let v_u16: Vec<u16> = vec![0x1234, 0xABCD];
80        assert_eq!(v_u16.encode(), &[0x02, 0x12, 0x34, 0xAB, 0xCD][..]);
81
82        let v_bool: Vec<bool> = vec![true, false, true];
83        assert_eq!(v_bool.encode(), &[0x03, 0x01, 0x00, 0x01][..]);
84
85        let v_empty_u32: Vec<u32> = Vec::new();
86        assert_eq!(v_empty_u32.encode(), &[0x00][..]);
87
88        // Test with a length that requires a multi-byte varint
89        let v_long_u8: Vec<u8> = vec![0xCC; 200]; // 200 = 0xC8 = 0x80 + 0x48 -> 0xC8 0x01
90        let mut expected_long_u8 = vec![0xC8, 0x01];
91        expected_long_u8.extend_from_slice(&[0xCC; 200]);
92        assert_eq!(v_long_u8.encode(), expected_long_u8.as_slice());
93    }
94}