Skip to main content

pamoja_codec/
bytes.rs

1//! A codec that carries raw bytes unchanged.
2
3use alloc::vec::Vec;
4
5use pamoja_core::Result;
6
7use crate::Codec;
8
9/// A no-op codec for payloads that are already byte buffers.
10///
11/// Encoding clones the buffer and decoding copies the input, so values pass
12/// through unchanged. This is the "raw framing" option for payloads that carry
13/// their own format, such as an image chunk or a pre-encoded frame.
14///
15/// # Examples
16///
17/// ```
18/// use pamoja_codec::{BytesCodec, Codec};
19///
20/// // A chunk of a camera image, which carries its own format and passes through untouched.
21/// let codec = BytesCodec;
22/// let chunk = b"the first rows of a trail camera image".to_vec();
23/// let encoded = codec.encode(&chunk).unwrap();
24/// assert_eq!(codec.decode(&encoded).unwrap(), chunk);
25/// ```
26#[derive(Clone, Copy, Debug, Default)]
27pub struct BytesCodec;
28
29impl Codec<Vec<u8>> for BytesCodec {
30    fn encode(&self, value: &Vec<u8>) -> Result<Vec<u8>> {
31        Ok(value.clone())
32    }
33
34    fn decode(&self, bytes: &[u8]) -> Result<Vec<u8>> {
35        Ok(bytes.to_vec())
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn round_trips_arbitrary_bytes() {
45        let codec = BytesCodec;
46        let payload = vec![1u8, 2, 3, 255, 0];
47        let encoded = codec.encode(&payload).expect("encode");
48        assert_eq!(encoded, payload);
49        assert_eq!(codec.decode(&encoded).expect("decode"), payload);
50    }
51
52    #[test]
53    fn round_trips_an_empty_buffer() {
54        let codec = BytesCodec;
55        let encoded = codec.encode(&Vec::new()).expect("encode");
56        assert!(encoded.is_empty());
57        assert!(codec.decode(&encoded).expect("decode").is_empty());
58    }
59}