Skip to main content

titan_api_codec/enc/
messagepack.rs

1//! Implementing encoding support for the [MessagePack] format.
2//!
3//! [MessagePack]: https://msgpack.org/index.html
4
5use super::common::{EncodeError, Encoder};
6
7use bytes::{BufMut, Bytes, BytesMut};
8use rmp_serde::encode::Serializer;
9
10/// Encodes messages to MessagePack binary format.
11#[derive(Default)]
12pub struct MessagePackEncoder {}
13
14impl Encoder for MessagePackEncoder {
15    fn encode<T>(&self, value: &T) -> Result<Bytes, EncodeError>
16    where
17        T: serde::Serialize,
18    {
19        let mut buffer = BytesMut::new().writer();
20        let mut serializer = Serializer::new(&mut buffer).with_struct_map();
21        value
22            .serialize(&mut serializer)
23            .map_err(|err| EncodeError::SerializationFailed(Box::new(err)))?;
24        Ok(buffer.into_inner().freeze())
25    }
26}
27
28#[cfg(test)]
29mod test {
30    use super::MessagePackEncoder;
31    use crate::enc::Encoder;
32
33    use bytes::Bytes;
34    use hex_literal::hex;
35
36    // Equivalent to TestStruct { a: 1234, b: "hello", c: [1, 2, 3, 4] }
37    const TEST_STRUCT_PACKED_NAMED: [u8; 22] = hex!("83a161cd04d2a162a568656c6c6fa163c40401020304");
38
39    #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
40    struct TestStruct {
41        a: u32,
42        b: String,
43        #[serde(with = "serde_bytes")]
44        c: Vec<u8>,
45    }
46
47    #[test]
48    fn test_encode() {
49        let test = TestStruct {
50            a: 1234,
51            b: "hello".into(),
52            c: vec![1, 2, 3, 4],
53        };
54        let encoder = MessagePackEncoder::default();
55
56        let encoded = encoder.encode(&test).expect("should encode to messagepack");
57        let expected = Bytes::from_static(&TEST_STRUCT_PACKED_NAMED);
58        assert_eq!(encoded, expected);
59    }
60}