1 use serde::{Deserialize, Serialize};
2 use serde_xml_rs::{self, from_str, to_string, EventReader, ParserConfig};
3 
4 #[derive(Debug, Serialize, Deserialize, PartialEq)]
5 struct Item {
6     name: String,
7     source: String,
8 }
9 
10 #[derive(Debug, Serialize, Deserialize, PartialEq)]
11 enum Node {
12     Boolean(bool),
13     Identifier { value: String, index: u32 },
14     EOF,
15 }
16 
17 #[derive(Debug, Serialize, Deserialize, PartialEq)]
18 struct Nodes {
19     #[serde(rename = "$value")]
20     items: Vec<Node>,
21 }
22 
23 #[test]
basic_struct()24 fn basic_struct() {
25     let src = r#"<?xml version="1.0" encoding="UTF-8"?><Item><name>Banana</name><source>Store</source></Item>"#;
26     let should_be = Item {
27         name: "Banana".to_string(),
28         source: "Store".to_string(),
29     };
30 
31     let item: Item = from_str(src).unwrap();
32     assert_eq!(item, should_be);
33 
34     let reserialized_item = to_string(&item).unwrap();
35     assert_eq!(src, reserialized_item);
36 }
37 
38 #[test]
round_trip_list_of_enums()39 fn round_trip_list_of_enums() {
40     // Construct some inputs
41     let nodes = Nodes {
42         items: vec![
43             Node::Boolean(true),
44             Node::Identifier {
45                 value: "foo".to_string(),
46                 index: 5,
47             },
48             Node::EOF,
49         ],
50     };
51 
52     let should_be = r#"<?xml version="1.0" encoding="UTF-8"?><Nodes><Boolean>true</Boolean><Identifier><value>foo</value><index>5</index></Identifier><EOF /></Nodes>"#;
53 
54     let serialized_nodes = to_string(&nodes).unwrap();
55     assert_eq!(serialized_nodes, should_be);
56 
57     // Then turn it back into a `Nodes` struct and make sure it's the same
58     // as the original
59     let deserialized_nodes: Nodes = from_str(serialized_nodes.as_str()).unwrap();
60     assert_eq!(deserialized_nodes, nodes);
61 }
62 
63 #[test]
whitespace_preserving_config()64 fn whitespace_preserving_config() {
65     // Test a configuration which does not clip whitespace from tags
66 
67     let src = r#"
68     <?xml version="1.0" encoding="UTF-8"?>
69     <Item>
70         <name>  space banana  </name>
71         <source>   fantasy costco   </source>
72     </Item>"#;
73 
74     let item_should_be = Item {
75         name: "  space banana  ".to_string(),
76         source: "   fantasy costco   ".to_string(),
77     };
78     let config = ParserConfig::new()
79         .trim_whitespace(false)
80         .whitespace_to_characters(false);
81     let mut deserializer =
82         serde_xml_rs::Deserializer::new(EventReader::new_with_config(src.as_bytes(), config));
83 
84     let item = Item::deserialize(&mut deserializer).unwrap();
85     assert_eq!(item, item_should_be);
86 
87     // Space outside values is not preserved.
88     let serialized_should_be =
89         "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Item><name>  space banana  </name><source>   fantasy costco   </source></Item>";
90     let reserialized_item = to_string(&item).unwrap();
91     assert_eq!(reserialized_item, serialized_should_be);
92 }
93