titan-api-codec 1.2.9

Helpers for encoding and decoding Titan API messages
Documentation
//! Implementing decoding support for the [MessagePack] format.
//!
//! [MessagePack]: https://msgpack.org/index.html

use super::common::{DecodeError, Decoder};

use bytes::{Buf, Bytes};
use serde::de::DeserializeOwned;

/// Decodes messages from the MessagePack binary format.
#[derive(Default)]
pub struct MessagePackDecoder {}

impl Decoder for MessagePackDecoder {
    fn decode<T>(&self, data: Bytes) -> Result<T, DecodeError>
    where
        T: DeserializeOwned,
    {
        rmp_serde::from_read(data.reader())
            .map_err(|err| DecodeError::DeserializationFailed(Box::new(err)))
    }
}

#[cfg(test)]
mod test {
    use crate::dec::Decoder;
    use bytes::Bytes;

    use super::MessagePackDecoder;
    use hex_literal::hex;

    // Equivalent to TestStruct { a: 1234, b: "hello", c: [1, 2, 3, 4] }
    const TEST_STRUCT_PACKED_NAMED: [u8; 22] = hex!("83a161cd04d2a162a568656c6c6fa163c40401020304");
    const TEST_STRUCT_PACKED_TUPLE: [u8; 16] = hex!("93cd04d2a568656c6c6fc40401020304");

    #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
    struct TestStruct {
        a: u32,
        b: String,
        #[serde(with = "serde_bytes")]
        c: Vec<u8>,
    }

    #[test]
    fn test_decode_named() {
        let decoder = MessagePackDecoder::default();
        let expected = TestStruct {
            a: 1234,
            b: "hello".into(),
            c: vec![1, 2, 3, 4],
        };
        let decoded = decoder
            .decode::<TestStruct>(Bytes::from_static(&TEST_STRUCT_PACKED_NAMED))
            .expect("should decode from msgpack data");
        assert_eq!(decoded, expected);
    }

    #[test]
    fn test_decode_tuple() {
        let decoder = MessagePackDecoder::default();
        let expected = TestStruct {
            a: 1234,
            b: "hello".into(),
            c: vec![1, 2, 3, 4],
        };
        let decoded = decoder
            .decode::<TestStruct>(Bytes::from_static(&TEST_STRUCT_PACKED_TUPLE))
            .expect("should decode from msgpack data");
        assert_eq!(decoded, expected);
    }
}