commonware_codec/
codec.rs1use crate::error::Error;
4use bytes::{Buf, BufMut, BytesMut};
5
6pub trait Codec: Sized {
8 fn write(&self, buf: &mut impl BufMut);
10
11 fn len_encoded(&self) -> usize;
13
14 fn encode(&self) -> BytesMut {
16 let len = self.len_encoded();
17 let mut buffer = BytesMut::with_capacity(len);
18 self.write(&mut buffer);
19 assert_eq!(buffer.len(), len);
20 buffer
21 }
22
23 fn read(buf: &mut impl Buf) -> Result<Self, Error>;
25
26 fn decode<B: Buf>(mut buf: B) -> Result<Self, Error> {
31 let result = Self::read(&mut buf);
32 let remaining = buf.remaining();
33 if remaining > 0 {
34 return Err(Error::ExtraData(remaining));
35 }
36 result
37 }
38}
39
40pub trait SizedCodec: Codec {
42 const LEN_ENCODED: usize;
44
45 fn len_encoded(&self) -> usize {
49 Self::LEN_ENCODED
50 }
51
52 fn encode_fixed<const N: usize>(&self) -> [u8; N] {
54 assert_eq!(
57 N,
58 Self::LEN_ENCODED,
59 "Can't encode {} bytes into {} bytes",
60 Self::LEN_ENCODED,
61 N
62 );
63
64 let mut array = [0u8; N];
65 let mut buf = &mut array[..];
66 self.write(&mut buf);
67 assert_eq!(buf.len(), 0);
68 array
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use crate::{Codec, Error};
76 use bytes::Bytes;
77
78 #[test]
79 fn test_insufficient_buffer() {
80 let mut reader = Bytes::from_static(&[0x01, 0x02]);
81 assert!(matches!(u32::read(&mut reader), Err(Error::EndOfBuffer)));
82 }
83
84 #[test]
85 fn test_extra_data() {
86 let encoded = Bytes::from_static(&[0x01, 0x02]);
87 assert!(matches!(u8::decode(encoded), Err(Error::ExtraData(1))));
88 }
89
90 #[test]
91 fn test_encode_fixed() {
92 let value = 42u32;
93 let encoded: [u8; 4] = value.encode_fixed();
94 let decoded = u32::decode(Bytes::copy_from_slice(&encoded)).unwrap();
95 assert_eq!(value, decoded);
96 }
97
98 #[test]
99 #[should_panic(expected = "Can't encode 4 bytes into 5 bytes")]
100 fn test_encode_fixed_panic() {
101 let _: [u8; 5] = 42u32.encode_fixed();
102 }
103}