blob: a042a7f16fe63bc9b33a7c669fb60202a21b1016 [file] [log] [blame]
#[macro_use]
extern crate serde_derive;
use rmp_serde as rmps;
use std::borrow::Cow;
use std::io::Cursor;
use serde::{Deserialize, Serialize};
use rmps::{Deserializer, Serializer};
#[test]
fn round_trip_option() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Foo {
v: Option<Vec<u8>>,
}
let expected = Foo { v: None };
let mut buf = Vec::new();
expected.serialize(&mut Serializer::new(&mut buf)).unwrap();
let mut de = Deserializer::new(Cursor::new(&buf[..]));
assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}
#[test]
fn round_trip_optional_enum() {
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub enum SimpleEnum {
Variant,
}
let expected = Some(SimpleEnum::Variant);
let mut buf = Vec::new();
expected.serialize(&mut Serializer::new(&mut buf)).unwrap();
let mut de = Deserializer::new(Cursor::new(&buf[..]));
assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}
#[test]
fn round_trip_cow() {
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Foo<'a> {
v: Cow<'a, [u8]>,
}
let expected = Foo { v : Cow::Borrowed(&[]) };
let mut buf = Vec::new();
expected.serialize(&mut Serializer::new(&mut buf)).unwrap();
let mut de = Deserializer::new(Cursor::new(&buf[..]));
assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}
#[test]
fn round_trip_option_cow() {
use std::borrow::Cow;
use std::io::Cursor;
use serde::Serialize;
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Foo<'a> {
v: Option<Cow<'a, [u8]>>,
}
let expected = Foo { v : None };
let mut buf = Vec::new();
expected.serialize(&mut Serializer::new(&mut buf)).unwrap();
let mut de = Deserializer::new(Cursor::new(&buf[..]));
assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}
#[test]
fn round_struct_like_enum() {
use serde::Serialize;
#[derive(Serialize, Deserialize, Debug, PartialEq)]
enum Enum {
A { data: u32 },
}
let expected = Enum::A { data: 42 };
let mut buf = Vec::new();
expected.serialize(&mut Serializer::new(&mut buf)).unwrap();
let mut de = Deserializer::new(&buf[..]);
assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}
#[test]
fn round_struct_like_enum_with_struct_map() {
use serde::Serialize;
#[derive(Serialize, Deserialize, Debug, PartialEq)]
enum Enum {
A { data: u32 },
}
let expected = Enum::A { data: 42 };
let mut buf = Vec::new();
expected
.serialize(&mut Serializer::new(&mut buf).with_struct_map())
.unwrap();
let mut de = Deserializer::new(&buf[..]);
assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}
#[test]
fn round_struct_like_enum_with_struct_tuple() {
use serde::Serialize;
#[derive(Serialize, Deserialize, Debug, PartialEq)]
enum Enum {
A { data: u32 },
}
let expected = Enum::A { data: 42 };
let mut buf = Vec::new();
expected
.serialize(&mut Serializer::new(&mut buf).with_struct_tuple())
.unwrap();
let mut de = Deserializer::new(&buf[..]);
assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}
#[test]
fn round_enum_with_newtype_struct() {
use serde::Serialize;
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Newtype(String);
#[derive(Serialize, Deserialize, Debug, PartialEq)]
enum Enum {
A(Newtype),
}
let expected = Enum::A(Newtype("le message".into()));
let mut buf = Vec::new();
expected.serialize(&mut Serializer::new(&mut buf)).unwrap();
let mut de = Deserializer::new(&buf[..]);
assert_eq!(expected, Deserialize::deserialize(&mut de).unwrap());
}
#[test]
fn round_trip_untagged_enum_with_enum_associated_data() {
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(untagged)]
enum Foo {
A(Bar),
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
enum Bar {
B,
C(String),
D(u64, u64, u64),
E{f1: String},
}
let data1_1 = Foo::A(Bar::B);
let bytes_1 = rmps::to_vec(&data1_1).unwrap();
let data1_2 = rmps::from_slice(&bytes_1).unwrap();
assert_eq!(data1_1, data1_2);
let data2_1 = Foo::A(Bar::C("Hello".into()));
let bytes_2 = rmps::to_vec(&data2_1).unwrap();
let data2_2 = rmps::from_slice(&bytes_2).unwrap();
assert_eq!(data2_1, data2_2);
let data3_1 = Foo::A(Bar::D(1,2,3));
let bytes_3 = rmps::to_vec(&data3_1).unwrap();
let data3_2 = rmps::from_slice(&bytes_3).unwrap();
assert_eq!(data3_1, data3_2);
let data4_1 = Foo::A(Bar::E{f1: "Hello".into()});
let bytes_4 = rmps::to_vec(&data4_1).unwrap();
let data4_2 = rmps::from_slice(&bytes_4).unwrap();
assert_eq!(data4_1, data4_2);
}
// Checks whether deserialization and serialization can both work with structs as maps
#[test]
fn round_struct_as_map() {
use crate::rmps::to_vec_named;
use crate::rmps::decode::from_slice;
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
struct Dog1 {
name: String,
age: u16,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
struct Dog2 {
age: u16,
name: String,
}
let dog1 = Dog1 {
name: "Frankie".into(),
age: 42,
};
let serialized: Vec<u8> = to_vec_named(&dog1).unwrap();
let deserialized: Dog2 = from_slice(&serialized).unwrap();
let check = Dog1 {
age: deserialized.age,
name: deserialized.name,
};
assert_eq!(dog1, check);
}
#[test]
fn round_struct_as_map_in_vec() {
// See: issue #205
use crate::rmps::decode::from_slice;
use crate::rmps::to_vec_named;
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
struct Dog1 {
name: String,
age: u16,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
struct Dog2 {
age: u16,
name: String,
}
let dog1 = Dog1 {
name: "Frankie".into(),
age: 42,
};
let data = vec![dog1];
let serialized: Vec<u8> = to_vec_named(&data).unwrap();
let deserialized: Vec<Dog2> = from_slice(&serialized).unwrap();
let dog2 = &deserialized[0];
assert_eq!(dog2.name, "Frankie");
assert_eq!(dog2.age, 42);
}
#[test]
fn round_trip_unit_struct() {
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
struct Message1 {
data: u8,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
struct Message2;
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
enum Messages {
Message1(Message1),
Message2(Message2),
}
let msg2 = Messages::Message2(Message2);
// struct-as-tuple
{
let serialized: Vec<u8> = rmps::to_vec(&msg2).unwrap();
let deserialized: Messages = rmps::from_slice(&serialized).unwrap();
assert_eq!(deserialized, msg2);
}
// struct-as-map
{
let serialized: Vec<u8> = rmps::to_vec_named(&msg2).unwrap();
let deserialized: Messages = rmps::from_slice(&serialized).unwrap();
assert_eq!(deserialized, msg2);
}
}
#[test]
#[ignore]
fn round_trip_unit_struct_untagged_enum() {
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
struct UnitStruct;
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
struct MessageA {
some_int: i32,
unit: UnitStruct,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
enum Messages {
MessageA(MessageA),
}
let msga = Messages::MessageA(MessageA {
some_int: 32,
unit: UnitStruct,
});
// struct-as-tuple
{
let serialized: Vec<u8> = rmps::to_vec(&msga).unwrap();
let deserialized: Messages = rmps::from_slice(&serialized).unwrap();
assert_eq!(deserialized, msga);
}
// struct-as-map
{
let serialized: Vec<u8> = rmps::to_vec_named(&msga).unwrap();
let deserialized: Messages = rmps::from_slice(&serialized).unwrap();
assert_eq!(deserialized, msga);
}
}
// Checks whether deserialization and serialization can both work with enum variants as strings
#[test]
fn round_variant_string() {
use crate::rmps::decode::from_slice;
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
enum Animal1 {
Dog { breed: String },
Cat,
Emu,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
enum Animal2 {
Emu,
Dog { breed: String },
Cat,
}
// use helper macro so that we can test many combinations at once. Needs to be a macro to deal
// with the serializer owning a reference to the Vec.
macro_rules! do_test {
($ser:expr) => {
{
let animal1 = Animal1::Dog { breed: "Pitbull".to_owned() };
let expected = Animal2::Dog { breed: "Pitbull".to_owned() };
let mut buf = Vec::new();
animal1.serialize(&mut $ser(&mut buf)).unwrap();
let deserialized: Animal2 = from_slice(&buf).unwrap();
assert_eq!(deserialized, expected);
}
}
}
do_test!(|b| Serializer::new(b).with_string_variants());
do_test!(|b| Serializer::new(b).with_struct_map().with_string_variants());
do_test!(|b| Serializer::new(b).with_struct_tuple().with_string_variants());
do_test!(|b| Serializer::new(b).with_string_variants().with_struct_map());
do_test!(|b| Serializer::new(b).with_string_variants().with_struct_tuple());
do_test!(|b| {
Serializer::new(b)
.with_string_variants()
.with_struct_tuple()
.with_struct_map()
.with_struct_tuple()
.with_struct_map()
});
do_test!(|b| Serializer::new(b).with_integer_variants().with_string_variants());
}
use std::net::{IpAddr, Ipv4Addr};
#[test]
fn roundtrip_ip_addr() {
assert_roundtrips(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)));
}
#[test]
fn roundtrip_some() {
#[derive(PartialEq, Debug, Serialize, Deserialize)]
struct Wrapper<T>(T);
assert_roundtrips(Some(99));
assert_roundtrips(Wrapper(Some(99)));
assert_roundtrips(Some(Wrapper(99)));
assert_roundtrips(Some("hi".to_string()));
}
#[ignore]
#[test]
fn roundtrip_some_failures() {
// FIXME
assert_roundtrips(Err::<(),_>(222));
assert_roundtrips(Some(None::<()>));
}
#[cfg(test)]
fn assert_roundtrips<T: PartialEq + std::fmt::Debug + Serialize + for<'a> Deserialize<'a>>(val: T) {
let seriaized = rmp_serde::to_vec(&val).unwrap();
let val2: T = match rmp_serde::from_slice(&seriaized) {
Ok(t) => t,
Err(e) => {
panic!("Does not deserialize: {}\nSerialized {:?}\nGot {:?}\n", e, val, rmpv::decode::value::read_value(&mut seriaized.as_slice()).expect("rmp didn't serialize corerctly at all"));
},
};
assert_eq!(val2, val);
}