Skip to main content

titan_api_codec/dec/
messagepack.rs

1//! Implementing decoding support for the [MessagePack] format.
2//!
3//! [MessagePack]: https://msgpack.org/index.html
4
5use super::common::{DecodeError, Decoder};
6
7use bytes::{Buf, Bytes};
8use serde::de::DeserializeOwned;
9
10/// Decodes messages from the MessagePack binary format.
11#[derive(Default)]
12pub struct MessagePackDecoder {}
13
14impl Decoder for MessagePackDecoder {
15    fn decode<T>(&self, data: Bytes) -> Result<T, DecodeError>
16    where
17        T: DeserializeOwned,
18    {
19        rmp_serde::from_read(data.reader())
20            .map_err(|err| DecodeError::DeserializationFailed(Box::new(err)))
21    }
22}
23
24#[cfg(test)]
25mod test {
26    use crate::dec::Decoder;
27    use bytes::Bytes;
28
29    use super::MessagePackDecoder;
30    use hex_literal::hex;
31
32    // Equivalent to TestStruct { a: 1234, b: "hello", c: [1, 2, 3, 4] }
33    const TEST_STRUCT_PACKED_NAMED: [u8; 22] = hex!("83a161cd04d2a162a568656c6c6fa163c40401020304");
34    const TEST_STRUCT_PACKED_TUPLE: [u8; 16] = hex!("93cd04d2a568656c6c6fc40401020304");
35
36    #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
37    struct TestStruct {
38        a: u32,
39        b: String,
40        #[serde(with = "serde_bytes")]
41        c: Vec<u8>,
42    }
43
44    #[test]
45    fn test_decode_named() {
46        let decoder = MessagePackDecoder::default();
47        let expected = TestStruct {
48            a: 1234,
49            b: "hello".into(),
50            c: vec![1, 2, 3, 4],
51        };
52        let decoded = decoder
53            .decode::<TestStruct>(Bytes::from_static(&TEST_STRUCT_PACKED_NAMED))
54            .expect("should decode from msgpack data");
55        assert_eq!(decoded, expected);
56    }
57
58    #[test]
59    fn test_decode_tuple() {
60        let decoder = MessagePackDecoder::default();
61        let expected = TestStruct {
62            a: 1234,
63            b: "hello".into(),
64            c: vec![1, 2, 3, 4],
65        };
66        let decoded = decoder
67            .decode::<TestStruct>(Bytes::from_static(&TEST_STRUCT_PACKED_TUPLE))
68            .expect("should decode from msgpack data");
69        assert_eq!(decoded, expected);
70    }
71}