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, EncodeSize, Error, RangeCfg, Read, Write};
7use bytes::{Buf, BufMut, Bytes};
8
9impl Write for Bytes {
10    #[inline]
11    fn write(&self, buf: &mut impl BufMut) {
12        self.len().write(buf);
13        buf.put_slice(self);
14    }
15}
16
17impl EncodeSize for Bytes {
18    #[inline]
19    fn encode_size(&self) -> usize {
20        self.len().encode_size() + self.len()
21    }
22}
23
24impl Read for Bytes {
25    type Cfg = RangeCfg<usize>;
26
27    #[inline]
28    fn read_cfg(buf: &mut impl Buf, range: &Self::Cfg) -> Result<Self, Error> {
29        let len = usize::read_cfg(buf, range)?;
30        at_least(buf, len)?;
31        Ok(buf.copy_to_bytes(len))
32    }
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38    use crate::{Decode, Encode};
39    #[cfg(not(feature = "std"))]
40    use alloc::vec;
41    use bytes::Bytes;
42
43    #[test]
44    fn test_bytes() {
45        let values = [
46            Bytes::new(),
47            Bytes::from_static(&[1, 2, 3]),
48            Bytes::from(vec![0; 300]),
49        ];
50        for value in values {
51            let encoded = value.encode();
52            let len = value.len();
53
54            // Valid decoding
55            let decoded = Bytes::decode_cfg(encoded, &(len..=len).into()).unwrap();
56            assert_eq!(value, decoded);
57
58            // Failure for too long
59            assert!(matches!(
60                Bytes::decode_cfg(value.encode(), &(0..len).into()),
61                Err(Error::InvalidLength(_))
62            ));
63
64            // Failure for too short
65            assert!(matches!(
66                Bytes::decode_cfg(value.encode(), &(len + 1..).into()),
67                Err(Error::InvalidLength(_))
68            ));
69        }
70    }
71
72    #[test]
73    fn test_conformity() {
74        assert_eq!(Bytes::new().encode(), &[0x00][..]);
75        assert_eq!(
76            Bytes::from_static(b"hello").encode(),
77            &[0x05, b'h', b'e', b'l', b'l', b'o'][..]
78        );
79        let long_bytes = Bytes::from(vec![0xAA; 150]);
80        let mut expected = vec![0x96, 0x01]; // Varint for 150
81        expected.extend_from_slice(&[0xAA; 150]);
82        assert_eq!(long_bytes.encode(), expected.as_slice());
83    }
84
85    #[cfg(feature = "arbitrary")]
86    mod conformance {
87        use super::*;
88        use crate::conformance::CodecConformance;
89        use arbitrary::Arbitrary;
90
91        /// Newtype wrapper to implement Arbitrary for [super::Bytes].
92        #[derive(Debug)]
93        struct Bytes(super::Bytes);
94
95        impl Write for Bytes {
96            fn write(&self, buf: &mut impl BufMut) {
97                self.0.write(buf);
98            }
99        }
100
101        impl EncodeSize for Bytes {
102            fn encode_size(&self) -> usize {
103                self.0.encode_size()
104            }
105        }
106
107        impl Read for Bytes {
108            type Cfg = RangeCfg<usize>;
109
110            fn read_cfg(buf: &mut impl Buf, cfg: &Self::Cfg) -> Result<Self, Error> {
111                Ok(Self(super::Bytes::read_cfg(buf, cfg)?))
112            }
113        }
114
115        impl Arbitrary<'_> for Bytes {
116            fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
117                let len = u.arbitrary::<u8>()?;
118                let bytes: Vec<u8> = u
119                    .arbitrary_iter()?
120                    .take(len as usize)
121                    .collect::<Result<Vec<_>, _>>()
122                    .unwrap();
123                Ok(Self(super::Bytes::from(bytes)))
124            }
125        }
126
127        commonware_conformance::conformance_tests! {
128            CodecConformance<Bytes>
129        }
130    }
131}