You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
237 lines
7.8 KiB
237 lines
7.8 KiB
4 months ago
|
use serde::Serialize;
|
||
|
use serde_cbor;
|
||
|
use serde_cbor::ser::{Serializer, SliceWrite};
|
||
|
|
||
|
#[macro_use]
|
||
|
extern crate serde_derive;
|
||
|
|
||
|
#[test]
|
||
|
fn test_simple_data_enum_roundtrip() {
|
||
|
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||
|
enum DataEnum {
|
||
|
A(u32),
|
||
|
B(f32),
|
||
|
}
|
||
|
|
||
|
let a = DataEnum::A(42);
|
||
|
|
||
|
let mut slice = [0u8; 64];
|
||
|
let writer = SliceWrite::new(&mut slice);
|
||
|
let mut serializer = Serializer::new(writer);
|
||
|
a.serialize(&mut serializer).unwrap();
|
||
|
let writer = serializer.into_inner();
|
||
|
let end = writer.bytes_written();
|
||
|
let slice = writer.into_inner();
|
||
|
let deserialized: DataEnum =
|
||
|
serde_cbor::de::from_slice_with_scratch(&slice[..end], &mut []).unwrap();
|
||
|
assert_eq!(a, deserialized);
|
||
|
}
|
||
|
|
||
|
#[cfg(feature = "std")]
|
||
|
mod std_tests {
|
||
|
use std::collections::BTreeMap;
|
||
|
|
||
|
use serde_cbor::ser::{IoWrite, Serializer};
|
||
|
use serde_cbor::value::Value;
|
||
|
use serde_cbor::{from_slice, to_vec};
|
||
|
|
||
|
pub fn to_vec_legacy<T>(value: &T) -> serde_cbor::Result<Vec<u8>>
|
||
|
where
|
||
|
T: serde::ser::Serialize,
|
||
|
{
|
||
|
let mut vec = Vec::new();
|
||
|
value.serialize(&mut Serializer::new(&mut IoWrite::new(&mut vec)).legacy_enums())?;
|
||
|
Ok(vec)
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||
|
enum Enum {
|
||
|
A,
|
||
|
B,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||
|
struct EnumStruct {
|
||
|
e: Enum,
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_enum() {
|
||
|
let enum_struct = EnumStruct { e: Enum::B };
|
||
|
let raw = &to_vec(&enum_struct).unwrap();
|
||
|
println!("raw enum {:?}", raw);
|
||
|
let re: EnumStruct = from_slice(raw).unwrap();
|
||
|
assert_eq!(enum_struct, re);
|
||
|
}
|
||
|
|
||
|
#[repr(u16)]
|
||
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||
|
enum ReprEnum {
|
||
|
A,
|
||
|
B,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||
|
struct ReprEnumStruct {
|
||
|
e: ReprEnum,
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_repr_enum() {
|
||
|
let repr_enum_struct = ReprEnumStruct { e: ReprEnum::B };
|
||
|
let re: ReprEnumStruct = from_slice(&to_vec(&repr_enum_struct).unwrap()).unwrap();
|
||
|
assert_eq!(repr_enum_struct, re);
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||
|
enum DataEnum {
|
||
|
A(u32),
|
||
|
B(bool, u8),
|
||
|
C { x: u8, y: String },
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_data_enum() {
|
||
|
let data_enum_a = DataEnum::A(4);
|
||
|
let re_a: DataEnum = from_slice(&to_vec(&data_enum_a).unwrap()).unwrap();
|
||
|
assert_eq!(data_enum_a, re_a);
|
||
|
let data_enum_b = DataEnum::B(true, 42);
|
||
|
let re_b: DataEnum = from_slice(&to_vec(&data_enum_b).unwrap()).unwrap();
|
||
|
assert_eq!(data_enum_b, re_b);
|
||
|
let data_enum_c = DataEnum::C {
|
||
|
x: 3,
|
||
|
y: "foo".to_owned(),
|
||
|
};
|
||
|
println!("{:?}", &to_vec(&data_enum_c).unwrap());
|
||
|
let re_c: DataEnum = from_slice(&to_vec(&data_enum_c).unwrap()).unwrap();
|
||
|
assert_eq!(data_enum_c, re_c);
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_serialize() {
|
||
|
assert_eq!(to_vec_legacy(&Enum::A).unwrap(), &[97, 65]);
|
||
|
assert_eq!(to_vec_legacy(&Enum::B).unwrap(), &[97, 66]);
|
||
|
assert_eq!(
|
||
|
to_vec_legacy(&DataEnum::A(42)).unwrap(),
|
||
|
&[130, 97, 65, 24, 42]
|
||
|
);
|
||
|
assert_eq!(
|
||
|
to_vec_legacy(&DataEnum::B(true, 9)).unwrap(),
|
||
|
&[131, 97, 66, 245, 9]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_newtype_struct() {
|
||
|
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||
|
pub struct Newtype(u8);
|
||
|
assert_eq!(to_vec(&142u8).unwrap(), to_vec(&Newtype(142u8)).unwrap());
|
||
|
assert_eq!(from_slice::<Newtype>(&[24, 142]).unwrap(), Newtype(142));
|
||
|
}
|
||
|
|
||
|
#[derive(Deserialize, PartialEq, Debug)]
|
||
|
enum Foo {
|
||
|
#[serde(rename = "require")]
|
||
|
Require,
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_variable_length_array() {
|
||
|
let slice = b"\x9F\x67\x72\x65\x71\x75\x69\x72\x65\xFF";
|
||
|
let value: Vec<Foo> = from_slice(slice).unwrap();
|
||
|
assert_eq!(value, [Foo::Require]);
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||
|
enum Bar {
|
||
|
Empty,
|
||
|
Number(i32),
|
||
|
Flag(String, bool),
|
||
|
Point { x: i32, y: i32 },
|
||
|
}
|
||
|
|
||
|
#[test]
|
||
|
fn test_enum_as_map() {
|
||
|
// unit variants serialize like bare strings
|
||
|
let empty_s = to_vec_legacy(&Bar::Empty).unwrap();
|
||
|
let empty_str_s = to_vec_legacy(&"Empty").unwrap();
|
||
|
assert_eq!(empty_s, empty_str_s);
|
||
|
|
||
|
// tuple-variants serialize like ["<variant>", values..]
|
||
|
let number_s = to_vec_legacy(&Bar::Number(42)).unwrap();
|
||
|
let number_vec = vec![Value::Text("Number".to_string()), Value::Integer(42)];
|
||
|
let number_vec_s = to_vec_legacy(&number_vec).unwrap();
|
||
|
assert_eq!(number_s, number_vec_s);
|
||
|
|
||
|
let flag_s = to_vec_legacy(&Bar::Flag("foo".to_string(), true)).unwrap();
|
||
|
let flag_vec = vec![
|
||
|
Value::Text("Flag".to_string()),
|
||
|
Value::Text("foo".to_string()),
|
||
|
Value::Bool(true),
|
||
|
];
|
||
|
let flag_vec_s = to_vec_legacy(&flag_vec).unwrap();
|
||
|
assert_eq!(flag_s, flag_vec_s);
|
||
|
|
||
|
// struct-variants serialize like ["<variant>", {struct..}]
|
||
|
let point_s = to_vec_legacy(&Bar::Point { x: 5, y: -5 }).unwrap();
|
||
|
let mut struct_map = BTreeMap::new();
|
||
|
struct_map.insert(Value::Text("x".to_string()), Value::Integer(5));
|
||
|
struct_map.insert(Value::Text("y".to_string()), Value::Integer(-5));
|
||
|
let point_vec = vec![
|
||
|
Value::Text("Point".to_string()),
|
||
|
Value::Map(struct_map.clone()),
|
||
|
];
|
||
|
let point_vec_s = to_vec_legacy(&point_vec).unwrap();
|
||
|
assert_eq!(point_s, point_vec_s);
|
||
|
|
||
|
// enum_as_map matches serde_json's default serialization for enums.
|
||
|
|
||
|
// unit variants still serialize like bare strings
|
||
|
let empty_s = to_vec(&Bar::Empty).unwrap();
|
||
|
assert_eq!(empty_s, empty_str_s);
|
||
|
|
||
|
// 1-element tuple variants serialize like {"<variant>": value}
|
||
|
let number_s = to_vec(&Bar::Number(42)).unwrap();
|
||
|
let mut number_map = BTreeMap::new();
|
||
|
number_map.insert("Number", 42);
|
||
|
let number_map_s = to_vec(&number_map).unwrap();
|
||
|
assert_eq!(number_s, number_map_s);
|
||
|
|
||
|
// multi-element tuple variants serialize like {"<variant>": [values..]}
|
||
|
let flag_s = to_vec(&Bar::Flag("foo".to_string(), true)).unwrap();
|
||
|
let mut flag_map = BTreeMap::new();
|
||
|
flag_map.insert(
|
||
|
"Flag",
|
||
|
vec![Value::Text("foo".to_string()), Value::Bool(true)],
|
||
|
);
|
||
|
let flag_map_s = to_vec(&flag_map).unwrap();
|
||
|
assert_eq!(flag_s, flag_map_s);
|
||
|
|
||
|
// struct-variants serialize like {"<variant>", {struct..}}
|
||
|
let point_s = to_vec(&Bar::Point { x: 5, y: -5 }).unwrap();
|
||
|
let mut point_map = BTreeMap::new();
|
||
|
point_map.insert("Point", Value::Map(struct_map));
|
||
|
let point_map_s = to_vec(&point_map).unwrap();
|
||
|
assert_eq!(point_s, point_map_s);
|
||
|
|
||
|
// deserialization of all encodings should just work
|
||
|
let empty_str_ds = from_slice(&empty_str_s).unwrap();
|
||
|
assert_eq!(Bar::Empty, empty_str_ds);
|
||
|
|
||
|
let number_vec_ds = from_slice(&number_vec_s).unwrap();
|
||
|
assert_eq!(Bar::Number(42), number_vec_ds);
|
||
|
let number_map_ds = from_slice(&number_map_s).unwrap();
|
||
|
assert_eq!(Bar::Number(42), number_map_ds);
|
||
|
|
||
|
let flag_vec_ds = from_slice(&flag_vec_s).unwrap();
|
||
|
assert_eq!(Bar::Flag("foo".to_string(), true), flag_vec_ds);
|
||
|
let flag_map_ds = from_slice(&flag_map_s).unwrap();
|
||
|
assert_eq!(Bar::Flag("foo".to_string(), true), flag_map_ds);
|
||
|
|
||
|
let point_vec_ds = from_slice(&point_vec_s).unwrap();
|
||
|
assert_eq!(Bar::Point { x: 5, y: -5 }, point_vec_ds);
|
||
|
let point_map_ds = from_slice(&point_map_s).unwrap();
|
||
|
assert_eq!(Bar::Point { x: 5, y: -5 }, point_map_ds);
|
||
|
}
|
||
|
}
|