use std::collections::{BTreeMap, HashMap};
use deser::de::{DeserializeDriver, DeserializeOwned, Recording};
use deser::{ContainerShape, Deserialize, Error, ErrorKind, Event};
fn ambiguous() -> ContainerShape {
let mut shape = ContainerShape::with_len(0);
shape.set_ambiguous_empty(true);
shape
}
fn deserialize<T: DeserializeOwned>(events: Vec<Event<'_>>) -> Result<T, Error> {
let mut out = None;
{
let mut driver = DeserializeDriver::new(&mut out);
for event in events {
driver.emit(event)?;
}
}
Ok(out.unwrap())
}
fn empty_seq() -> Vec<Event<'static>> {
vec![Event::SeqStart(ambiguous()), Event::SeqEnd]
}
fn empty_map() -> Vec<Event<'static>> {
vec![Event::MapStart(ambiguous()), Event::MapEnd]
}
#[derive(Debug, PartialEq, Deserialize)]
struct Settings {
#[deser(default)]
theme: Option<String>,
#[deser(default)]
flags: Vec<String>,
}
#[derive(Debug, PartialEq, Deserialize)]
struct Required {
name: String,
}
#[test]
fn test_seq_as_map() {
assert_eq!(
deserialize::<BTreeMap<String, u32>>(empty_seq()).unwrap(),
BTreeMap::new()
);
assert_eq!(
deserialize::<HashMap<u32, u32>>(empty_seq()).unwrap(),
HashMap::new()
);
assert_eq!(
deserialize::<Settings>(empty_seq()).unwrap(),
Settings {
theme: None,
flags: vec![]
}
);
assert_eq!(
deserialize::<Option<Box<BTreeMap<String, u32>>>>(empty_seq()).unwrap(),
Some(Box::default())
);
let err = deserialize::<Required>(empty_seq()).unwrap_err();
assert_eq!(err.message(), "missing field `name`");
assert_eq!(
deserialize::<Vec<u32>>(empty_seq()).unwrap(),
Vec::<u32>::new()
);
}
#[test]
fn test_map_as_seq() {
assert_eq!(
deserialize::<Vec<u32>>(empty_map()).unwrap(),
Vec::<u32>::new()
);
assert_eq!(
deserialize::<Option<Vec<String>>>(empty_map()).unwrap(),
Some(vec![])
);
assert_eq!(deserialize::<[u32; 0]>(empty_map()).unwrap(), []);
assert_eq!(
deserialize::<BTreeMap<String, u32>>(empty_map()).unwrap(),
BTreeMap::new()
);
}
#[test]
fn test_nested() {
let events = vec![
Event::map_start(),
"a".into(),
Event::SeqStart(ambiguous()),
Event::SeqEnd,
"b".into(),
Event::MapStart(ambiguous()),
Event::MapEnd,
Event::MapEnd,
];
#[derive(Debug, PartialEq, Deserialize)]
struct Outer {
a: BTreeMap<String, u32>,
b: Vec<Vec<u8>>,
}
assert_eq!(
deserialize::<Outer>(events).unwrap(),
Outer {
a: BTreeMap::new(),
b: vec![]
}
);
let events = vec![
Event::seq_start(),
Event::MapStart(ambiguous()),
Event::MapEnd,
Event::SeqEnd,
];
assert_eq!(
deserialize::<Vec<Vec<u8>>>(events).unwrap(),
vec![Vec::<u8>::new()]
);
}
#[test]
fn test_rejected() {
let events = vec![Event::SeqStart(ContainerShape::with_len(0)), Event::SeqEnd];
let err = deserialize::<BTreeMap<String, u32>>(events).unwrap_err();
assert_eq!(err.message(), "unexpected sequence, expected BTreeMap");
let mut shape = ContainerShape::new();
shape.set_ambiguous_empty(true);
assert!(!shape.is_ambiguous_empty());
let events = vec![Event::SeqStart(shape), Event::SeqEnd];
assert!(deserialize::<BTreeMap<String, u32>>(events).is_err());
let err = deserialize::<u32>(empty_seq()).unwrap_err();
assert_eq!(err.message(), "unexpected sequence, expected u32");
let err = deserialize::<u32>(empty_map()).unwrap_err();
assert_eq!(err.message(), "unexpected map, expected u32");
}
#[test]
fn test_items_in_empty_container() {
let events = vec![Event::SeqStart(ambiguous()), 1u64.into(), Event::SeqEnd];
let err = deserialize::<BTreeMap<String, u32>>(events).unwrap_err();
assert_eq!(err.kind(), ErrorKind::InvalidState);
let events = vec![
Event::SeqStart(ambiguous()),
Event::seq_start(),
Event::SeqEnd,
Event::SeqEnd,
];
assert!(deserialize::<BTreeMap<String, u32>>(events).is_err());
}
#[test]
fn test_untagged() {
#[derive(Debug, PartialEq, Deserialize)]
#[deser(untagged)]
enum Data {
Map(BTreeMap<String, u32>),
List(Vec<u32>),
}
assert_eq!(
deserialize::<Data>(empty_seq()).unwrap(),
Data::Map(BTreeMap::new())
);
}
#[test]
fn test_recording() {
let recording = deserialize::<Recording>(empty_seq()).unwrap();
let mut out = None::<BTreeMap<String, u32>>;
let mut driver_out = None::<()>;
let mut driver = DeserializeDriver::new(&mut driver_out);
recording
.replay(
<BTreeMap<String, u32>>::deserialize_into(&mut out, driver.state_mut()),
driver.state_mut(),
)
.unwrap();
assert_eq!(out, Some(BTreeMap::new()));
}