mod common;
use common::init_logger;
use serde::Deserialize;
use serde_xml_rs::{from_str, Deserializer};
#[derive(Debug, Deserialize, PartialEq)]
struct Item {
name: String,
source: String,
}
#[test]
fn simple_struct_from_attributes() {
init_logger();
let s = r##"
"##;
let item: Item = from_str(s).unwrap();
assert_eq!(
item,
Item {
name: "hello".to_string(),
source: "world.rs".to_string(),
}
);
}
#[test]
fn multiple_roots_attributes() {
init_logger();
let s = r##"
"##;
let item: Vec- = from_str(s).unwrap();
assert_eq!(
item,
vec![
Item {
name: "hello".to_string(),
source: "world.rs".to_string(),
},
Item {
name: "hello".to_string(),
source: "world.rs".to_string(),
},
]
);
}
#[test]
fn simple_struct_from_attribute_and_child() {
init_logger();
let s = r##"
-
"##;
let item: Item = from_str(s).unwrap();
assert_eq!(
item,
Item {
name: "hello".to_string(),
source: "world.rs".to_string(),
}
);
}
#[derive(Debug, Deserialize, PartialEq)]
struct Project {
name: String,
#[serde(rename = "item", default)]
items: Vec- ,
}
#[test]
fn nested_collection() {
init_logger();
let s = r##"
"##;
let project: Project = from_str(s).unwrap();
assert_eq!(
project,
Project {
name: "my_project".to_string(),
items: vec![
Item {
name: "hello1".to_string(),
source: "world1.rs".to_string(),
},
Item {
name: "hello2".to_string(),
source: "world2.rs".to_string(),
},
],
}
);
}
#[derive(Debug, Deserialize, PartialEq)]
enum MyEnum {
A(String),
B { name: String, flag: bool },
C,
}
#[derive(Debug, Deserialize, PartialEq)]
struct MyEnums {
#[serde(rename = "$value")]
items: Vec,
}
#[test]
fn collection_of_enums() {
init_logger();
let s = r##"
test
"##;
let project: MyEnums = from_str(s).unwrap();
assert_eq!(
project,
MyEnums {
items: vec![
MyEnum::A("test".to_string()),
MyEnum::B {
name: "hello".to_string(),
flag: true,
},
MyEnum::C,
],
}
);
}
#[test]
fn out_of_order_collection() {
#[derive(Debug, Deserialize, PartialEq)]
struct Collection {
a: Vec,
b: Vec,
c: C,
}
#[derive(Debug, Deserialize, PartialEq)]
struct A {
name: String,
}
#[derive(Debug, Deserialize, PartialEq)]
struct B {
name: String,
}
#[derive(Debug, Deserialize, PartialEq)]
struct C {
name: String,
}
init_logger();
let in_xml = r#"
"#;
let should_be = Collection {
a: vec![
A { name: "a1".into() },
A { name: "a2".into() },
A { name: "a3".into() },
A { name: "a4".into() },
],
b: vec![B { name: "b1".into() }, B { name: "b2".into() }],
c: C { name: "c".into() },
};
let mut de = Deserializer::new_from_reader(in_xml.as_bytes()).non_contiguous_seq_elements(true);
let actual = Collection::deserialize(&mut de).unwrap();
assert_eq!(should_be, actual);
}
#[test]
fn nested_out_of_order_collection() {
#[derive(Debug, Deserialize, PartialEq)]
struct OuterCollection {
a: A,
inner: Vec,
}
#[derive(Debug, Deserialize, PartialEq)]
struct InnerCollection {
b: Vec,
c: Vec,
}
#[derive(Debug, Deserialize, PartialEq)]
struct A {
name: String,
}
#[derive(Debug, Deserialize, PartialEq)]
struct B {
name: String,
}
#[derive(Debug, Deserialize, PartialEq)]
struct C {
name: String,
}
init_logger();
let in_xml = r#"
"#;
let should_be = OuterCollection {
a: A { name: "a".into() },
inner: vec![
InnerCollection {
b: vec![B { name: "b1".into() }, B { name: "b2".into() }],
c: vec![C { name: "c1".into() }, C { name: "c2".into() }],
},
InnerCollection {
b: vec![B { name: "b3".into() }, B { name: "b4".into() }],
c: vec![C { name: "c3".into() }, C { name: "c4".into() }],
},
],
};
let mut de = Deserializer::new_from_reader(in_xml.as_bytes()).non_contiguous_seq_elements(true);
let actual = OuterCollection::deserialize(&mut de).unwrap();
assert_eq!(should_be, actual);
}
#[test]
fn out_of_order_tuple() {
#[derive(Debug, Deserialize, PartialEq)]
struct Collection {
val: (A, B, C),
other: A,
}
#[derive(Debug, Deserialize, PartialEq)]
struct A {
name_a: String,
}
#[derive(Debug, Deserialize, PartialEq)]
struct B {
name_b: String,
}
#[derive(Debug, Deserialize, PartialEq)]
struct C {
name_c: String,
}
init_logger();
let in_xml = r#"
"#;
let should_be = Collection {
val: (
A {
name_a: "a1".into(),
},
B { name_b: "b".into() },
C { name_c: "c".into() },
),
other: A {
name_a: "a2".into(),
},
};
let mut de = Deserializer::new_from_reader(in_xml.as_bytes()).non_contiguous_seq_elements(true);
let actual = Collection::deserialize(&mut de).unwrap();
assert_eq!(should_be, actual);
}
/// Ensure that identically-named elements at different depths are not deserialized as if they were
/// at the same depth.
#[test]
fn nested_collection_repeated_elements() {
#[derive(Debug, Deserialize, PartialEq)]
struct OuterCollection {
a: Vec,
inner: Inner,
}
#[derive(Debug, Deserialize, PartialEq)]
struct Inner {
a: A,
}
#[derive(Debug, Deserialize, PartialEq)]
struct A {
name: String,
}
init_logger();
let in_xml = r#"
"#;
let should_be = OuterCollection {
a: vec![A { name: "a1".into() }, A { name: "a3".into() }],
inner: Inner {
a: A { name: "a2".into() },
},
};
let mut de = Deserializer::new_from_reader(in_xml.as_bytes()).non_contiguous_seq_elements(true);
let actual = OuterCollection::deserialize(&mut de).unwrap();
assert_eq!(should_be, actual);
}