use core::any::type_name;
use serde::{de::DeserializeOwned, Serialize};
use crate::Binary;
use crate::{StdError, StdResult};
pub fn from_msgpack<T: DeserializeOwned>(value: impl AsRef<[u8]>) -> StdResult<T> {
rmp_serde::from_read(value.as_ref()).map_err(|e| StdError::parse_err(type_name::<T>(), e))
}
pub fn to_msgpack_vec<T>(data: &T) -> StdResult<Vec<u8>>
where
T: Serialize + ?Sized,
{
rmp_serde::to_vec_named(data).map_err(|e| StdError::serialize_err(type_name::<T>(), e))
}
pub fn to_msgpack_binary<T>(data: &T) -> StdResult<Binary>
where
T: Serialize + ?Sized,
{
to_msgpack_vec(data).map(Binary::new)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Int128, Int256, Int512, Int64, Uint128, Uint256, Uint512, Uint64};
use serde::Deserialize;
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(rename_all = "snake_case")]
enum SomeMsg {
Refund {},
ReleaseAll {
image: String,
amount: u32,
time: u64,
karma: i32,
},
Cowsay {
text: String,
},
}
fn refund_test_vector() -> (SomeMsg, &'static [u8]) {
let msg = SomeMsg::Refund {};
let serialized = &[129, 166, 114, 101, 102, 117, 110, 100, 128];
(msg, serialized)
}
fn release_all_test_vector() -> (SomeMsg, &'static [u8]) {
let msg = SomeMsg::ReleaseAll {
image: "foo".to_string(),
amount: 42,
time: 18446744073709551615,
karma: -17,
};
let serialized = &[
129, 171, 114, 101, 108, 101, 97, 115, 101, 95, 97, 108, 108, 132, 165, 105, 109, 97,
103, 101, 163, 102, 111, 111, 166, 97, 109, 111, 117, 110, 116, 42, 164, 116, 105, 109,
101, 207, 255, 255, 255, 255, 255, 255, 255, 255, 165, 107, 97, 114, 109, 97, 239,
];
(msg, serialized)
}
fn special_chars_test_vector() -> (SomeMsg, &'static [u8]) {
let msg = SomeMsg::Cowsay {
text: "foo\"bar\\\"bla🦴👁🦶🏻".to_string(),
};
let serialized = &[
129, 166, 99, 111, 119, 115, 97, 121, 129, 164, 116, 101, 120, 116, 188, 102, 111, 111,
34, 98, 97, 114, 92, 34, 98, 108, 97, 240, 159, 166, 180, 240, 159, 145, 129, 240, 159,
166, 182, 240, 159, 143, 187,
];
(msg, serialized)
}
#[test]
fn to_msgpack_vec_works() {
let (msg, expected) = refund_test_vector();
let serialized = to_msgpack_vec(&msg).unwrap();
assert_eq!(serialized, expected);
let (msg, expected) = release_all_test_vector();
let serialized = to_msgpack_vec(&msg).unwrap();
assert_eq!(serialized, expected);
}
#[test]
fn from_msgpack_works() {
let (msg, serialized) = refund_test_vector();
let deserialized: SomeMsg = from_msgpack(serialized).unwrap();
assert_eq!(deserialized, msg);
let (msg, serialized) = release_all_test_vector();
let deserialized: SomeMsg = from_msgpack(serialized).unwrap();
assert_eq!(deserialized, msg);
}
#[test]
fn from_msgpack_or_binary() {
let msg = SomeMsg::Refund {};
let serialized: Binary = to_msgpack_binary(&msg).unwrap();
let parse_binary: SomeMsg = from_msgpack(&serialized).unwrap();
assert_eq!(parse_binary, msg);
let parse_slice: SomeMsg = from_msgpack(serialized.as_slice()).unwrap();
assert_eq!(parse_slice, msg);
}
#[test]
fn from_msgpack_works_for_special_chars() {
let (msg, serialized) = special_chars_test_vector();
let deserialized: SomeMsg = from_msgpack(serialized).unwrap();
assert_eq!(deserialized, msg);
}
#[test]
fn deserialize_modified_field_order() {
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct TestV1 {
a: String,
b: u32,
c: u64,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct TestV2 {
b: u32,
c: u64,
a: String,
}
let v1 = TestV1 {
a: "foo".to_string(),
b: 42,
c: 18446744073709551615,
};
let v2: TestV2 = from_msgpack(to_msgpack_vec(&v1).unwrap()).unwrap();
assert_eq!(
v2,
TestV2 {
b: 42,
c: 18446744073709551615,
a: "foo".to_string()
}
);
}
#[test]
fn deserialize_new_fields() {
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct TestV1 {
a: String,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct TestV2 {
a: String,
#[serde(default)]
b: u32,
}
let v1 = TestV1 {
a: "foo".to_string(),
};
let v2: TestV2 = from_msgpack(to_msgpack_vec(&v1).unwrap()).unwrap();
assert_eq!(
v2,
TestV2 {
a: "foo".to_string(),
b: 0
}
);
}
#[test]
fn deserialize_new_fields_in_the_middle() {
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct TestV1 {
a: String,
b: u32,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct TestV2 {
a: String,
#[serde(default)]
c: u8,
b: u32,
}
let v1 = TestV1 {
a: "foo".to_string(),
b: 999999,
};
let v2: TestV2 = from_msgpack(to_msgpack_vec(&v1).unwrap()).unwrap();
assert_eq!(
v2,
TestV2 {
a: "foo".to_string(),
c: 0,
b: 999999,
}
);
}
#[test]
fn msgpack_serialization_for_boolean_types() {
let serialized = to_msgpack_vec(&false).unwrap();
assert_eq!(serialized, [0xc2]);
let serialized = to_msgpack_vec(&true).unwrap();
assert_eq!(serialized, [0xc3]);
}
#[test]
fn msgpack_serialization_for_integer_types() {
{
let serialized = to_msgpack_vec(&0u8).unwrap();
assert_eq!(serialized, [0]);
let serialized = to_msgpack_vec(&0u16).unwrap();
assert_eq!(serialized, [0]);
let serialized = to_msgpack_vec(&0u32).unwrap();
assert_eq!(serialized, [0]);
let serialized = to_msgpack_vec(&0u64).unwrap();
assert_eq!(serialized, [0]);
let serialized = to_msgpack_vec(&0i64).unwrap();
assert_eq!(serialized, [0]);
let serialized = to_msgpack_vec(&7u8).unwrap();
assert_eq!(serialized, [7]);
let serialized = to_msgpack_vec(&7u16).unwrap();
assert_eq!(serialized, [7]);
let serialized = to_msgpack_vec(&7u32).unwrap();
assert_eq!(serialized, [7]);
let serialized = to_msgpack_vec(&7u64).unwrap();
assert_eq!(serialized, [7]);
let serialized = to_msgpack_vec(&127u32).unwrap();
assert_eq!(serialized, [127]);
let serialized = to_msgpack_vec(&-1i32).unwrap();
assert_eq!(serialized, [255]);
let serialized = to_msgpack_vec(&-1i64).unwrap();
assert_eq!(serialized, [255]);
let serialized = to_msgpack_vec(&-10i64).unwrap();
assert_eq!(serialized, [246]);
let serialized = to_msgpack_vec(&-24i64).unwrap();
assert_eq!(serialized, [232]);
let serialized = to_msgpack_vec(&128u32).unwrap();
assert_eq!(serialized, [0xcc, 128]);
let serialized = to_msgpack_vec(&237u32).unwrap();
assert_eq!(serialized, [0xcc, 237]);
let serialized = to_msgpack_vec(&1000u32).unwrap();
assert_eq!(serialized, [0xcd, 3, 232]);
let serialized = to_msgpack_vec(&u32::MAX).unwrap();
assert_eq!(serialized, [0xce, 255, 255, 255, 255]);
let serialized = to_msgpack_vec(&575747839886u64).unwrap();
assert_eq!(serialized, [0xcf, 0, 0, 0, 134, 13, 62, 215, 142]);
let serialized = to_msgpack_vec(&u64::MAX).unwrap();
assert_eq!(serialized, [0xcf, 255, 255, 255, 255, 255, 255, 255, 255]);
let serialized = to_msgpack_vec(&i8::MIN).unwrap();
assert_eq!(serialized, [0xd0, 128]);
let serialized = to_msgpack_vec(&-111i8).unwrap();
assert_eq!(serialized, [0xd0, 145]);
let serialized = to_msgpack_vec(&i16::MIN).unwrap();
assert_eq!(serialized, [0xd1, 128, 0]);
let serialized = to_msgpack_vec(&i32::MIN).unwrap();
assert_eq!(serialized, [0xd2, 128, 0, 0, 0]);
let serialized = to_msgpack_vec(&i64::MIN).unwrap();
assert_eq!(serialized, [0xd3, 128, 0, 0, 0, 0, 0, 0, 0]);
}
{
assert_eq!(
to_msgpack_vec(&0u128).unwrap(),
[0xc4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
);
assert_eq!(
to_msgpack_vec(&1u128).unwrap(),
[0xc4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
);
assert_eq!(
to_msgpack_vec(&17u128).unwrap(),
[0xc4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17]
);
assert_eq!(
to_msgpack_vec(&u128::MAX).unwrap(),
[
0xc4, 16, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255
]
);
assert_eq!(
to_msgpack_vec(&0i128).unwrap(),
[0xc4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
);
assert_eq!(
to_msgpack_vec(&1i128).unwrap(),
[0xc4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
);
assert_eq!(
to_msgpack_vec(&17i128).unwrap(),
[0xc4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17]
);
assert_eq!(
to_msgpack_vec(&-1i128).unwrap(),
[
0xc4, 16, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255
]
);
assert_eq!(
to_msgpack_vec(&i128::MIN).unwrap(),
[0xc4, 16, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
);
assert_eq!(
to_msgpack_vec(&i128::MAX).unwrap(),
[
0xc4, 16, 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255
]
);
}
{
let s = to_msgpack_vec(&Uint64::zero()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'0']); let s = to_msgpack_vec(&Uint128::zero()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'0']); let s = to_msgpack_vec(&Uint256::zero()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'0']); let s = to_msgpack_vec(&Uint512::zero()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'0']); let s = to_msgpack_vec(&Uint64::one()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'1']); let s = to_msgpack_vec(&Uint128::one()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'1']); let s = to_msgpack_vec(&Uint256::one()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'1']); let s = to_msgpack_vec(&Uint512::one()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'1']); let s = to_msgpack_vec(&Uint64::MAX).unwrap();
assert_eq!(
s,
[
0b10100000 ^ 20,
b'1',
b'8',
b'4',
b'4',
b'6',
b'7',
b'4',
b'4',
b'0',
b'7',
b'3',
b'7',
b'0',
b'9',
b'5',
b'5',
b'1',
b'6',
b'1',
b'5'
]
); }
{
let s = to_msgpack_vec(&Int64::zero()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'0']); let s = to_msgpack_vec(&Int128::zero()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'0']); let s = to_msgpack_vec(&Int256::zero()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'0']); let s = to_msgpack_vec(&Int512::zero()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'0']); let s = to_msgpack_vec(&Int64::one()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'1']); let s = to_msgpack_vec(&Int128::one()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'1']); let s = to_msgpack_vec(&Int256::one()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'1']); let s = to_msgpack_vec(&Int512::one()).unwrap();
assert_eq!(s, [0b10100000 ^ 1, b'1']); let s = to_msgpack_vec(&Int64::from(15i32)).unwrap();
assert_eq!(s, [0b10100000 ^ 2, b'1', b'5']); let s = to_msgpack_vec(&Int128::from(15i32)).unwrap();
assert_eq!(s, [0b10100000 ^ 2, b'1', b'5']); let s = to_msgpack_vec(&Int256::from(15i32)).unwrap();
assert_eq!(s, [0b10100000 ^ 2, b'1', b'5']); let s = to_msgpack_vec(&Int512::from(15i32)).unwrap();
assert_eq!(s, [0b10100000 ^ 2, b'1', b'5']); let s = to_msgpack_vec(&Int64::from(-1i64)).unwrap();
assert_eq!(s, [0b10100000 ^ 2, b'-', b'1']); let s = to_msgpack_vec(&Int128::from(-1i64)).unwrap();
assert_eq!(s, [0b10100000 ^ 2, b'-', b'1']); let s = to_msgpack_vec(&Int256::from(-1i64)).unwrap();
assert_eq!(s, [0b10100000 ^ 2, b'-', b'1']); let s = to_msgpack_vec(&Int512::from(-1i64)).unwrap();
assert_eq!(s, [0b10100000 ^ 2, b'-', b'1']); }
}
}