commonware_codec/types/
bytes.rs

1//! Implementations of Codec for byte types.
2//!
3//! For portability and consistency between architectures,
4//! the length of the [`Bytes`] must fit within a [`u32`].
5
6use crate::{util::at_least, varint, EncodeSize, Error, RangeConfig, Read, Write};
7use bytes::{Buf, BufMut, Bytes};
8
9impl Write for Bytes {
10    #[inline]
11    fn write(&self, buf: &mut impl BufMut) {
12        let len = u32::try_from(self.len()).expect("Bytes length exceeds u32");
13        varint::write(len, buf);
14        buf.put_slice(self);
15    }
16}
17
18impl EncodeSize for Bytes {
19    #[inline]
20    fn encode_size(&self) -> usize {
21        let len = u32::try_from(self.len()).expect("Bytes length exceeds u32");
22        varint::size(len) + self.len()
23    }
24}
25
26impl<R: RangeConfig> Read<R> for Bytes {
27    #[inline]
28    fn read_cfg(buf: &mut impl Buf, cfg: &R) -> Result<Self, Error> {
29        let len32 = varint::read::<u32>(buf)?;
30        let len = usize::try_from(len32).map_err(|_| Error::InvalidVarint)?;
31        if !cfg.contains(&len) {
32            return Err(Error::InvalidLength(len));
33        }
34        at_least(buf, len)?;
35        Ok(buf.copy_to_bytes(len))
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42    use crate::{Decode, Encode};
43    use bytes::Bytes;
44
45    #[test]
46    fn test_bytes() {
47        let values = [
48            Bytes::new(),
49            Bytes::from_static(&[1, 2, 3]),
50            Bytes::from(vec![0; 300]),
51        ];
52        for value in values {
53            let encoded = value.encode();
54            assert_eq!(
55                encoded.len(),
56                varint::size(value.len() as u64) + value.len()
57            );
58            let len = value.len();
59
60            // Valid decoding
61            let decoded = Bytes::decode_cfg(encoded, &(len..=len)).unwrap();
62            assert_eq!(value, decoded);
63
64            // Failure for too long
65            matches!(
66                Bytes::decode_cfg(value.encode(), &(0..len)),
67                Err(Error::InvalidLength(_))
68            );
69
70            // Failure for too short
71            matches!(
72                Bytes::decode_cfg(value.encode(), &(len + 1..)),
73                Err(Error::InvalidLength(_))
74            );
75        }
76    }
77}