use std::collections::BTreeMap;
use lazy_static::lazy_static;
use maplit::btreemap;
use crate::*;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct PayloadValue {
id: Option<i64>,
list: Option<Vec<String>>,
}
type Payload = BTreeMap<i32, PayloadValue>;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct NoPayloadReordered {
name: String,
t: u64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct WithPayload {
t: u64,
name: String,
payload: Payload,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct WithOptionalPayload {
t: u64,
name: String,
payload: Option<Payload>,
}
lazy_static! {
static ref NO_PAYLOAD_REORDERED: NoPayloadReordered = NoPayloadReordered {
name: "alice".to_owned(),
t: 1234,
};
static ref WITH_PAYLOAD: WithPayload = WithPayload {
name: "alice".to_owned(),
t: 1234,
payload: btreemap! {
1 => PayloadValue {
id: Some(1),
list: Some(vec!["a".to_owned()]),
},
2 => PayloadValue {
id: Some(1),
list: Some(vec!["b".to_owned(), "cd".to_owned()]),
}
},
};
static ref WITH_NO_PAYLOAD: WithOptionalPayload = WithOptionalPayload {
name: "alice".to_owned(),
t: 1234,
payload: None,
};
static ref WITH_SOME_PAYLOAD: WithOptionalPayload = WithOptionalPayload {
name: "alice".to_owned(),
t: 1234,
payload: Some(btreemap! {
1 => PayloadValue {
id: Some(1),
list: Some(vec!["a".to_owned()]),
},
2 => PayloadValue {
id: Some(1),
list: Some(vec!["b".to_owned(), "cd".to_owned()]),
}
}),
};
}
#[test]
fn test_serialize_deserialize() {
{
let bytes = serde_cbor::to_vec(&*NO_PAYLOAD_REORDERED).unwrap();
let res: NoPayloadReordered = serde_cbor::from_slice(&bytes).unwrap();
assert_eq!(res, *NO_PAYLOAD_REORDERED);
}
{
let bytes = serde_cbor::to_vec(&*WITH_PAYLOAD).unwrap();
let res: WithPayload = serde_cbor::from_slice(&bytes).unwrap();
assert_eq!(res, *WITH_PAYLOAD);
}
{
let bytes = serde_cbor::to_vec(&*WITH_NO_PAYLOAD).unwrap();
let res: WithOptionalPayload = serde_cbor::from_slice(&bytes).unwrap();
assert_eq!(res, *WITH_NO_PAYLOAD);
}
{
let bytes = serde_cbor::to_vec(&*WITH_SOME_PAYLOAD).unwrap();
let res: WithOptionalPayload = serde_cbor::from_slice(&bytes).unwrap();
assert_eq!(res, *WITH_SOME_PAYLOAD);
}
}
#[test]
fn test_removing_field() {
let bytes = serde_cbor::to_vec(&*WITH_PAYLOAD).unwrap();
let res: NoPayloadReordered = serde_cbor::from_slice(&bytes).unwrap();
assert_eq!(res, *NO_PAYLOAD_REORDERED);
}
#[test]
fn test_removing_optional_field() {
let bytes = serde_cbor::to_vec(&*WITH_SOME_PAYLOAD).unwrap();
let res: NoPayloadReordered = serde_cbor::from_slice(&bytes).unwrap();
assert_eq!(res, *NO_PAYLOAD_REORDERED);
}
#[test]
fn test_adding_field() {
let bytes = serde_cbor::to_vec(&*NO_PAYLOAD_REORDERED).unwrap();
serde_cbor::from_slice::<WithPayload>(&bytes)
.expect_err("Should have failed deserializing due to missing required field");
}
#[test]
fn test_adding_optional_field() {
let bytes = serde_cbor::to_vec(&*NO_PAYLOAD_REORDERED).unwrap();
let res: WithOptionalPayload = serde_cbor::from_slice(&bytes).unwrap();
assert_eq!(res, *WITH_NO_PAYLOAD);
}
#[test]
fn test_changing_required_to_optional() {
let bytes = serde_cbor::to_vec(&*WITH_PAYLOAD).unwrap();
let res: WithOptionalPayload = serde_cbor::from_slice(&bytes).unwrap();
assert_eq!(res, *WITH_SOME_PAYLOAD);
}
#[test]
fn test_changing_optional_to_required() {
let bytes = serde_cbor::to_vec(&*WITH_NO_PAYLOAD).unwrap();
serde_cbor::from_slice::<WithPayload>(&bytes)
.expect_err("Should have failed deserializing as Option<T> cannot be deserialized to T");
}