Skip to main content

pamoja_codec/
cbor.rs

1//! A compact CBOR codec built on [`ciborium`].
2
3use serde::de::DeserializeOwned;
4use serde::Serialize;
5
6use pamoja_core::{Error, Result};
7
8use crate::Codec;
9
10/// A codec that serializes values to and from CBOR.
11///
12/// CBOR is a compact, self-describing binary format, which makes it the default
13/// choice for constrained devices and metered radio links where every byte costs
14/// power or money. The codec works for any type that implements [`serde::Serialize`]
15/// and [`serde::de::DeserializeOwned`].
16///
17/// # Examples
18///
19/// ```
20/// use pamoja_codec::{CborCodec, Codec};
21///
22/// let codec = CborCodec;
23/// let value = (1u8, "ok".to_owned());
24/// let encoded = codec.encode(&value).unwrap();
25/// let decoded: (u8, String) = codec.decode(&encoded).unwrap();
26/// assert_eq!(decoded, value);
27/// ```
28#[derive(Clone, Copy, Debug, Default)]
29pub struct CborCodec;
30
31impl<T> Codec<T> for CborCodec
32where
33    T: Serialize + DeserializeOwned,
34{
35    fn encode(&self, value: &T) -> Result<Vec<u8>> {
36        let mut buffer = Vec::new();
37        ciborium::into_writer(value, &mut buffer)
38            .map_err(|error| Error::Codec(error.to_string()))?;
39        Ok(buffer)
40    }
41
42    fn decode(&self, bytes: &[u8]) -> Result<T> {
43        ciborium::from_reader(bytes).map_err(|error| Error::Codec(error.to_string()))
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn round_trips_a_tuple() {
53        let codec = CborCodec;
54        let value = (42u32, true, vec![1u8, 2, 3]);
55        let encoded = codec.encode(&value).expect("encode");
56        let decoded: (u32, bool, Vec<u8>) = codec.decode(&encoded).expect("decode");
57        assert_eq!(decoded, value);
58    }
59
60    #[test]
61    fn decoding_truncated_input_is_a_codec_error() {
62        let codec = CborCodec;
63        let result: Result<(u32, u32)> = codec.decode(&[]);
64        assert!(matches!(result, Err(Error::Codec(_))));
65    }
66}