cratestack_codec_cbor/
lib.rs1use cratestack_core::{CoolCodec, CoolError};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Default)]
5pub struct CborCodec;
6
7impl CoolCodec for CborCodec {
8 const CONTENT_TYPE: &'static str = "application/cbor";
9
10 fn encode<T: Serialize + ?Sized>(&self, value: &T) -> Result<Vec<u8>, CoolError> {
11 minicbor_serde::to_vec(value)
19 .map_err(|error| CoolError::Codec(format!("failed to encode CBOR body: {error}")))
20 }
21
22 fn decode<T: for<'de> Deserialize<'de>>(&self, bytes: &[u8]) -> Result<T, CoolError> {
23 minicbor_serde::from_slice(bytes)
24 .map_err(|error| CoolError::Codec(format!("failed to decode CBOR body: {error}")))
25 }
26}
27
28#[cfg(test)]
29mod tests {
30 use cratestack_core::CoolCodec;
31
32 use super::CborCodec;
33
34 #[test]
35 fn round_trips_value() {
36 let codec = CborCodec;
37 let bytes = codec
38 .encode(&vec!["cool", "stack"])
39 .expect("encode should succeed");
40 let value: Vec<String> = codec.decode(&bytes).expect("decode should succeed");
41
42 assert_eq!(value, vec!["cool".to_owned(), "stack".to_owned()]);
43 }
44
45 #[test]
46 fn optional_none_round_trips_as_cbor_null() {
47 let codec = CborCodec;
54 let bytes = codec.encode(&Option::<String>::None).expect("encode none");
55 assert_eq!(bytes, vec![0xf6]);
56 let decoded: Option<String> = codec.decode(&bytes).expect("decode none");
57 assert!(decoded.is_none());
58 }
59}