use zerompk_derive::{FromMessagePack, ToMessagePack};
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct PointArray {
x: i32,
y: i32,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct PrimitiveVectors {
flags: Vec<bool>,
u8s: Vec<u8>,
u16s: Vec<u16>,
u32s: Vec<u32>,
u64s: Vec<u64>,
i8s: Vec<i8>,
i16s: Vec<i16>,
i32s: Vec<i32>,
i64s: Vec<i64>,
f32s: Vec<f32>,
f64s: Vec<f64>,
}
#[test]
fn derive_primitive_vectors_use_standard_array_encoding_with_exact_buffer() {
let value = PrimitiveVectors {
flags: vec![true, false, true],
u8s: vec![0, 127, 128, u8::MAX],
u16s: vec![0, 128, 256, u16::MAX],
u32s: vec![0, 256, 65_536, u32::MAX],
u64s: vec![0, 65_536, 1 << 32, u64::MAX],
i8s: vec![i8::MIN, -32, 0, i8::MAX],
i16s: vec![i16::MIN, -128, 128, i16::MAX],
i32s: vec![i32::MIN, -32_768, 32_768, i32::MAX],
i64s: vec![i64::MIN, i32::MIN as i64 - 1, i64::MAX],
f32s: vec![f32::MIN, -0.0, f32::MAX],
f64s: vec![f64::MIN, -0.0, f64::MAX],
};
let mut roomy_output = [0; 512];
let len = zerompk::to_msgpack(&value, &mut roomy_output).unwrap();
let mut exact_output = vec![0; len];
let exact_len = zerompk::to_msgpack(&value, &mut exact_output).unwrap();
assert_eq!(exact_len, len);
assert_eq!(exact_output, roomy_output[..len]);
assert_eq!(
zerompk::from_msgpack::<PrimitiveVectors>(&exact_output).unwrap(),
value
);
}
#[derive(ToMessagePack)]
#[msgpack(array)]
struct PrimitiveSequences<'a> {
slice: &'a [i32],
array: [f64; 3],
cow: std::borrow::Cow<'a, [u32]>,
}
#[test]
fn derive_primitive_slices_arrays_and_cows_use_standard_array_encoding() {
let slice = [i32::MIN, -1, 0, i32::MAX];
let value = PrimitiveSequences {
slice: &slice,
array: [f64::MIN, -0.0, f64::MAX],
cow: std::borrow::Cow::Borrowed(&[0, 128, u32::MAX]),
};
let mut output = [0; 128];
let len = zerompk::to_msgpack(&value, &mut output).unwrap();
let expected_value = (value.slice, value.array, value.cow.as_ref());
let mut expected = [0; 128];
let expected_len = zerompk::to_msgpack(&expected_value, &mut expected).unwrap();
assert_eq!(&output[..len], &expected[..expected_len]);
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
struct DefaultReprPoint {
x: i32,
y: i32,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
enum DefaultReprEvent {
A,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(map)]
struct PointMap {
x: i32,
y: i32,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct PointArrayWithIndex {
#[msgpack(key = 0)]
x: i32,
#[msgpack(key = 2)]
y: i32,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(map)]
struct PointMapWithKey {
#[msgpack(key = "px")]
x: i32,
#[msgpack(key = "py")]
y: i32,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(map)]
struct LongMapKeyPoint {
#[msgpack(key = "abcdefghX")]
x: i32,
#[msgpack(key = "zzzzzzzzz")]
y: i32,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(map)]
struct Str8MapKey {
#[msgpack(key = "abcdefghijklmnopqrstuvwxyz123456")]
value: u8,
}
#[test]
fn derive_map_preencodes_str8_key() {
let value = Str8MapKey { value: 42 };
let data = zerompk::to_msgpack_vec(&value).unwrap();
let mut expected = vec![0x81, 0xd9, 32];
expected.extend_from_slice(b"abcdefghijklmnopqrstuvwxyz123456");
expected.push(42);
assert_eq!(data, expected);
assert_eq!(zerompk::from_msgpack::<Str8MapKey>(&data).unwrap(), value);
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
struct UnitStruct;
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
struct EmptyTupleStruct();
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
struct TupleStruct(i32, String);
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct EmptyStruct {}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(map)]
struct EmptyStructWithMap {}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
struct NewtypeStruct(i32);
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct IgnoreArrayField {
x: i32,
#[msgpack(ignore)]
note: String,
y: i32,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(map)]
struct IgnoreMapField {
x: i32,
#[msgpack(ignore)]
note: String,
y: i32,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
enum Event {
A,
#[msgpack(key = "p")]
#[msgpack(array)]
Point {
x: i32,
y: i32,
},
#[msgpack(key = 2)]
Tuple(#[msgpack(key = 0)] i32, #[msgpack(key = 2)] i32),
#[msgpack(key = "m")]
#[msgpack(map)]
Mapped {
#[msgpack(key = "x1")]
x: i32,
y: i32,
},
#[msgpack(array)]
IgnoredNamed {
x: i32,
#[msgpack(ignore)]
note: String,
y: i32,
},
#[msgpack(map)]
IgnoredMapNamed {
x: i32,
#[msgpack(ignore)]
note: String,
y: i32,
},
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(map)]
enum MapEvent {
A,
#[msgpack(key = "p")]
#[msgpack(array)]
Point {
x: i32,
y: i32,
},
#[msgpack(key = 2)]
Tuple(#[msgpack(key = 0)] i32, #[msgpack(key = 2)] i32),
#[msgpack(key = "m")]
#[msgpack(map)]
Mapped {
#[msgpack(key = "x1")]
x: i32,
y: i32,
},
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(map)]
enum SyncedDataType {
Header,
Page([u8; 16]),
}
#[derive(serde::Deserialize, Debug, PartialEq)]
enum SerdeSyncedDataType {
Header,
Page([u8; 16]),
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(c_enum)]
#[repr(u8)]
enum HttpStatus {
Ok = 0,
NotFound = 4,
InternalServerError = 5,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(c_enum)]
enum BasicLevel {
Low,
Medium,
High,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(c_enum)]
#[repr(i8)]
enum ReprI8Enum {
MinusOne = -1,
Zero = 0,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct RecursiveNode {
next: Option<Box<RecursiveNode>>,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct BorrowedPayload<'a> {
text: &'a str,
data: &'a [u8],
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct BorrowedList<'a> {
foo: Vec<&'a str>,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct GenericWrapper<T> {
value: T,
other_field: bool,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct CowPayload<'a> {
data: std::borrow::Cow<'a, [u8]>,
nums: std::borrow::Cow<'a, [i32]>,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct CowPayloadAsArray<'a> {
#[msgpack(as_bytes = false)]
data: std::borrow::Cow<'a, [u8]>,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct CowPayloadAsBinExplicit<'a> {
#[msgpack(as_bytes = true)]
data: std::borrow::Cow<'a, [u8]>,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct VecPayloadDefault {
data: Vec<u8>,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct VecPayloadAsArray {
#[msgpack(as_bytes = false)]
data: Vec<u8>,
}
#[derive(ToMessagePack, FromMessagePack, Debug, PartialEq)]
#[msgpack(array)]
struct VecPayloadAsBinExplicit {
#[msgpack(as_bytes = true)]
data: Vec<u8>,
}
fn recursive_node_msgpack(depth: usize) -> Vec<u8> {
let mut out = vec![0x91; depth]; out.push(0xc0); out
}
#[test]
fn derive_array_default() {
let point = PointArray { x: 10, y: 20 };
let data = zerompk::to_msgpack_vec(&point).unwrap();
assert_eq!(data, vec![0x92, 0x0a, 0x14]);
let decoded: PointArray = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, point);
}
#[test]
fn derive_generic_struct() {
let value = GenericWrapper {
value: "borrowed",
other_field: true,
};
let data = zerompk::to_msgpack_vec(&value).unwrap();
let decoded: GenericWrapper<&str> = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_default_repr_for_named_struct() {
let point = DefaultReprPoint { x: 10, y: 20 };
let data = zerompk::to_msgpack_vec(&point).unwrap();
#[cfg(not(feature = "default-as-map"))]
assert_eq!(data, vec![0x92, 0x0a, 0x14]);
#[cfg(feature = "default-as-map")]
assert_eq!(data, vec![0x82, 0xa1, b'x', 0x0a, 0xa1, b'y', 0x14]);
let decoded: DefaultReprPoint = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, point);
}
#[test]
fn derive_default_repr_for_enum() {
let value = DefaultReprEvent::A;
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0xa1, b'A']);
let decoded: DefaultReprEvent = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_map_with_attribute() {
let point = PointMap { x: 10, y: 20 };
let data = zerompk::to_msgpack_vec(&point).unwrap();
assert_eq!(data, vec![0x82, 0xa1, b'x', 0x0a, 0xa1, b'y', 0x14]);
let decoded: PointMap = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, point);
}
#[test]
fn derive_array_with_field_index_and_nil_gap() {
let point = PointArrayWithIndex { x: 10, y: 20 };
let data = zerompk::to_msgpack_vec(&point).unwrap();
assert_eq!(data, vec![0x93, 0x0a, 0xc0, 0x14]);
let decoded: PointArrayWithIndex = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, point);
}
#[test]
fn derive_map_with_field_key() {
let point = PointMapWithKey { x: 10, y: 20 };
let data = zerompk::to_msgpack_vec(&point).unwrap();
assert_eq!(
data,
vec![0x82, 0xa2, b'p', b'x', 0x0a, 0xa2, b'p', b'y', 0x14]
);
let decoded: PointMapWithKey = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, point);
}
#[test]
fn derive_map_rejects_unknown_key_with_same_len_and_prefix() {
let data = vec![
0x82, 0xa9, b'a', b'b', b'c', b'd', b'e', b'f', b'g', b'h', b'Y', 0x01, 0xa9, b'z', b'z',
b'z', b'z', b'z', b'z', b'z', b'z', b'z', 0x02,
];
let err = zerompk::from_msgpack::<LongMapKeyPoint>(&data).unwrap_err();
assert!(matches!(
err,
zerompk::Error::UnknownKey(ref key) if key == "abcdefghY"
));
}
#[test]
fn derive_unit_struct() {
let unit = UnitStruct;
let data = zerompk::to_msgpack_vec(&unit).unwrap();
assert_eq!(data, vec![0xc0]);
let decoded: UnitStruct = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, unit);
}
#[test]
fn derive_empty_struct() {
let empty = EmptyStruct {};
let data = zerompk::to_msgpack_vec(&empty).unwrap();
assert_eq!(data, vec![0x90]);
let decoded: EmptyStruct = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, empty);
}
#[test]
fn derive_empty_struct_with_map() {
let empty = EmptyStructWithMap {};
let data = zerompk::to_msgpack_vec(&empty).unwrap();
assert_eq!(data, vec![0x80]);
let decoded: EmptyStructWithMap = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, empty);
}
#[test]
fn derive_empty_tuple_struct() {
let empty = EmptyTupleStruct();
let data = zerompk::to_msgpack_vec(&empty).unwrap();
assert_eq!(data, vec![0x90]);
let decoded: EmptyTupleStruct = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, empty);
}
#[test]
fn derive_tuple_struct() {
let tuple = TupleStruct(42, "hello".to_string());
let data = zerompk::to_msgpack_vec(&tuple).unwrap();
assert_eq!(data, vec![0x92, 0x2a, 0xa5, b'h', b'e', b'l', b'l', b'o']);
let decoded: TupleStruct = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, tuple);
}
#[test]
fn derive_borrowed_fields_are_zero_copy_and_bin() {
let value = BorrowedPayload {
text: "hi",
data: &[1, 2, 3],
};
let encoded = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(
encoded,
vec![0x92, 0xa2, b'h', b'i', 0xc4, 0x03, 0x01, 0x02, 0x03]
);
let decoded: BorrowedPayload = zerompk::from_msgpack(&encoded).unwrap();
assert_eq!(decoded, value);
assert_eq!(decoded.text.as_ptr(), encoded[2..4].as_ptr());
assert_eq!(decoded.data.as_ptr(), encoded[6..9].as_ptr());
}
#[test]
fn derive_nested_borrowed_vec_of_str() {
let value = BorrowedList {
foo: vec!["hello", "world"],
};
let encoded = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(
encoded,
vec![
0x91, 0x92, 0xa5, b'h', b'e', b'l', b'l', b'o', 0xa5, b'w', b'o', b'r', b'l', b'd',
]
);
let decoded: BorrowedList = zerompk::from_msgpack(&encoded).unwrap();
assert_eq!(decoded, value);
assert_eq!(decoded.foo[0].as_ptr(), encoded[3..8].as_ptr());
assert_eq!(decoded.foo[1].as_ptr(), encoded[9..14].as_ptr());
}
#[test]
fn derive_cow_u8_is_bin_and_other_cow_slice_is_array() {
let value = CowPayload {
data: std::borrow::Cow::Borrowed(&[1, 2, 3]),
nums: std::borrow::Cow::Borrowed(&[10, 20]),
};
let encoded = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(
encoded,
vec![
0x92, 0xc4, 0x03, 0x01, 0x02, 0x03, 0x92, 0x0a, 0x14, ]
);
let decoded: CowPayload = zerompk::from_msgpack(&encoded).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_cow_u8_with_as_bytes_false_is_array() {
let value = CowPayloadAsArray {
data: std::borrow::Cow::Borrowed(&[1, 2, 3]),
};
let encoded = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(
encoded,
vec![
0x91, 0x93, 0x01, 0x02, 0x03, ]
);
let decoded: CowPayloadAsArray = zerompk::from_msgpack(&encoded).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_cow_u8_with_as_bytes_true_is_bin() {
let value = CowPayloadAsBinExplicit {
data: std::borrow::Cow::Borrowed(&[1, 2, 3]),
};
let encoded = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(encoded, vec![0x91, 0xc4, 0x03, 0x01, 0x02, 0x03]);
let decoded: CowPayloadAsBinExplicit = zerompk::from_msgpack(&encoded).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_vec_u8_default_is_bin() {
let value = VecPayloadDefault {
data: vec![1, 2, 3],
};
let encoded = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(encoded, vec![0x91, 0xc4, 0x03, 0x01, 0x02, 0x03]);
let decoded: VecPayloadDefault = zerompk::from_msgpack(&encoded).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_vec_u8_with_as_bytes_false_is_array() {
let value = VecPayloadAsArray {
data: vec![1, 2, 3],
};
let encoded = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(encoded, vec![0x91, 0x93, 0x01, 0x02, 0x03]);
let decoded: VecPayloadAsArray = zerompk::from_msgpack(&encoded).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_vec_u8_with_as_bytes_true_is_bin() {
let value = VecPayloadAsBinExplicit {
data: vec![1, 2, 3],
};
let encoded = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(encoded, vec![0x91, 0xc4, 0x03, 0x01, 0x02, 0x03]);
let decoded: VecPayloadAsBinExplicit = zerompk::from_msgpack(&encoded).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_struct_newtype() {
let value = NewtypeStruct(42);
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0x2a]);
let decoded: NewtypeStruct = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_array_ignores_field() {
let value = IgnoreArrayField {
x: 10,
note: "ignored".to_string(),
y: 20,
};
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0x92, 0x0a, 0x14]);
let decoded: IgnoreArrayField = zerompk::from_msgpack(&data).unwrap();
assert_eq!(
decoded,
IgnoreArrayField {
x: 10,
note: String::new(),
y: 20,
}
);
}
#[test]
fn derive_map_ignores_field() {
let value = IgnoreMapField {
x: 10,
note: "ignored".to_string(),
y: 20,
};
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0x82, 0xa1, b'x', 0x0a, 0xa1, b'y', 0x14]);
let decoded: IgnoreMapField = zerompk::from_msgpack(&data).unwrap();
assert_eq!(
decoded,
IgnoreMapField {
x: 10,
note: String::new(),
y: 20,
}
);
}
#[test]
fn derive_enum_unit_variant() {
let value = Event::A;
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0xa1, b'A']);
let decoded: Event = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_enum_named_array_variant() {
let value = Event::Point { x: 10, y: 20 };
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0x92, 0xa1, b'p', 0x92, 0x0a, 0x14]);
let decoded: Event = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_enum_tuple_variant_with_gap() {
let value = Event::Tuple(10, 20);
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0x92, 0x02, 0x93, 0x0a, 0xc0, 0x14]);
let decoded: Event = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_enum_named_map_variant() {
let value = Event::Mapped { x: 10, y: 20 };
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(
data,
vec![
0x92, 0xa1, b'm', 0x82, 0xa2, b'x', b'1', 0x0a, 0xa1, b'y', 0x14
]
);
let decoded: Event = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_map_enum_unit_variant() {
let value = MapEvent::A;
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0xa1, b'A']);
let decoded: MapEvent = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_map_enum_matches_serde_externally_tagged_layout() {
let header_data = zerompk::to_msgpack_vec(&SyncedDataType::Header).unwrap();
assert_eq!(header_data, vec![0xa6, b'H', b'e', b'a', b'd', b'e', b'r']);
let serde_header: SerdeSyncedDataType = rmp_serde::from_slice(&header_data).unwrap();
assert_eq!(serde_header, SerdeSyncedDataType::Header);
let page = SyncedDataType::Page([7; 16]);
let page_data = zerompk::to_msgpack_vec(&page).unwrap();
let serde_page: SerdeSyncedDataType = rmp_serde::from_slice(&page_data).unwrap();
assert_eq!(serde_page, SerdeSyncedDataType::Page([7; 16]));
let decoded: SyncedDataType = zerompk::from_msgpack(&page_data).unwrap();
assert_eq!(decoded, page);
let io_decoded: SyncedDataType = zerompk::read_msgpack(page_data.as_slice()).unwrap();
assert_eq!(io_decoded, page);
}
#[test]
fn derive_map_enum_named_array_variant() {
let value = MapEvent::Point { x: 10, y: 20 };
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0x81, 0xa1, b'p', 0x92, 0x0a, 0x14]);
let decoded: MapEvent = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_map_enum_tuple_variant_with_gap() {
let value = MapEvent::Tuple(10, 20);
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0x81, 0x02, 0x93, 0x0a, 0xc0, 0x14]);
let decoded: MapEvent = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_map_enum_named_map_variant() {
let value = MapEvent::Mapped { x: 10, y: 20 };
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(
data,
vec![
0x81, 0xa1, b'm', 0x82, 0xa2, b'x', b'1', 0x0a, 0xa1, b'y', 0x14
]
);
let decoded: MapEvent = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_enum_named_array_variant_ignores_field() {
let value = Event::IgnoredNamed {
x: 10,
note: "ignored".to_string(),
y: 20,
};
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(
data,
vec![
0x92, 0xac, b'I', b'g', b'n', b'o', b'r', b'e', b'd', b'N', b'a', b'm', b'e', b'd',
0x92, 0x0a, 0x14,
]
);
let decoded: Event = zerompk::from_msgpack(&data).unwrap();
assert_eq!(
decoded,
Event::IgnoredNamed {
x: 10,
note: String::new(),
y: 20,
}
);
}
#[test]
fn derive_enum_named_map_variant_ignores_field() {
let value = Event::IgnoredMapNamed {
x: 10,
note: "ignored".to_string(),
y: 20,
};
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(
data,
vec![
0x92, 0xaf, b'I', b'g', b'n', b'o', b'r', b'e', b'd', b'M', b'a', b'p', b'N', b'a',
b'm', b'e', b'd', 0x82, 0xa1, b'x', 0x0a, 0xa1, b'y', 0x14,
]
);
let decoded: Event = zerompk::from_msgpack(&data).unwrap();
assert_eq!(
decoded,
Event::IgnoredMapNamed {
x: 10,
note: String::new(),
y: 20,
}
);
}
#[test]
fn derive_c_enum_with_explicit_discriminant() {
let value = HttpStatus::InternalServerError;
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0x05]);
let decoded: HttpStatus = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_c_enum_with_implicit_discriminant() {
let value = BasicLevel::Medium;
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0x01]);
let decoded: BasicLevel = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_c_enum_with_signed_discriminant() {
let value = ReprI8Enum::MinusOne;
let data = zerompk::to_msgpack_vec(&value).unwrap();
assert_eq!(data, vec![0xff]);
let decoded: ReprI8Enum = zerompk::from_msgpack(&data).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn derive_c_enum_unknown_value_is_error() {
let err = zerompk::from_msgpack::<HttpStatus>(&[0x03]).unwrap_err();
assert!(matches!(err, zerompk::Error::InvalidMarker(0)));
}
#[test]
fn derive_deserialize_depth_limit_max_is_ok() {
let data = recursive_node_msgpack(500);
let decoded: RecursiveNode = zerompk::from_msgpack(&data).unwrap();
let mut depth = 0usize;
let mut cur = &decoded;
while let Some(next) = &cur.next {
depth += 1;
cur = next;
}
assert_eq!(depth + 1, 500);
}
#[test]
fn derive_deserialize_depth_limit_exceeded() {
let data = recursive_node_msgpack(501);
let err = zerompk::from_msgpack::<RecursiveNode>(&data).unwrap_err();
assert!(matches!(
err,
zerompk::Error::DepthLimitExceeded { max: 500 }
));
}