1 pub use rstest::{fixture, rstest};
2 use simple_logger::SimpleLogger;
3 use std::fmt::Debug;
4
5 #[fixture]
logger()6 fn logger() {
7 let _ = SimpleLogger::new().init();
8 }
9
10 mod de {
11 use super::*;
12 use serde::Deserialize;
13 use serde_xml_rs::from_str;
14
15 #[rstest]
16 #[case::string("<bla>This is a String</bla>", "This is a String".to_string())]
17 #[case::string("<bla></bla>", "".to_string())]
18 #[case::string("<bla> </bla>", "".to_string())]
19 #[case::string("<bla><boom/></bla>", "<boom/>".to_string())]
20 #[case::string("<bla>♫</bla>", "♫".to_string())]
21 #[case::string("<bla>♫</bla>", "♫".to_string())]
22 #[case::string("<bla>♫<![CDATA[<cookies/>]]>♫</bla>", "♫<cookies/>♫".to_string())]
23 #[case::i64("<bla>0</bla>", 0i64)]
24 #[case::i64("<bla>-2</bla>", -2i64)]
25 #[case::i64("<bla>-1234</bla>", -1234i64)]
26 #[case::i64("<bla> -1234 </bla>", -1234i64)]
27 #[case::u64("<bla>0</bla>", 0u64)]
28 #[case::u64("<bla>1234</bla>", 1234u64)]
29 #[case::u64("<bla> 1234 </bla>", 1234u64)]
30 #[case::bool("<bla>true</bla>", true)]
31 #[case::bool("<bla>false</bla>", false)]
32 #[case::unit("<bla/>", ())]
33 #[case::f64("<bla>3.0</bla>", 3.0f64)]
34 #[case::f64("<bla>3.1</bla>", 3.1f64)]
35 #[case::f64("<bla>-1.2</bla>", -1.2f64)]
36 #[case::f64("<bla>0.4</bla>", 0.4f64)]
37 #[case::f64("<bla>0.4e5</bla>", 0.4e5f64)]
38 #[case::f64("<bla>0.4e15</bla>", 0.4e15f64)]
39 #[case::f64_precision_troubles("<bla>0.4e-01</bla>", 0.4e-01f64)]
40 #[case::f64("<bla> 0.4e-01 </bla>", 0.4e-01f64)]
41 #[case::option("<bla/>", Some("".to_string()))]
42 #[case::option("<bla></bla>", Some("".to_string()))]
43 #[case::option("<bla> </bla>", Some("".to_string()))]
44 #[case::option("<bla>42</bla>", Some("42".to_string()))]
element_ok<T, 'de>(_logger: (), #[case] document: &str, #[case] expected: T) where T: Deserialize<'de> + Debug + PartialEq,45 fn element_ok<T, 'de>(_logger: (), #[case] document: &str, #[case] expected: T)
46 where
47 T: Deserialize<'de> + Debug + PartialEq,
48 {
49 let actual: T = from_str(document).unwrap();
50 assert_eq!(actual, expected);
51 }
52
53 #[rstest]
54 #[case("<bla>verum</bla>", Some(true))]
element_ko<T, 'de>(_logger: (), #[case] document: &str, #[case] _type: Option<T>) where T: Deserialize<'de> + Debug + PartialEq,55 fn element_ko<T, 'de>(_logger: (), #[case] document: &str, #[case] _type: Option<T>)
56 where
57 T: Deserialize<'de> + Debug + PartialEq,
58 {
59 let actual: Result<T, _> = from_str(document);
60 assert!(actual.is_err());
61 }
62
63 #[derive(PartialEq, Debug, Deserialize)]
64 struct DummyAttribute<T> {
65 foo: T,
66 }
67
68 #[rstest]
69 #[case(r#"<bla foo="true"/>"#, DummyAttribute { foo: true })]
70 #[case(r#"<bla foo="false"/>"#, DummyAttribute { foo: false })]
71 #[case(r#"<bla foo="1"/>"#, DummyAttribute { foo: true })]
72 #[case(r#"<bla foo="0"/>"#, DummyAttribute { foo: false })]
attribute_ok<T, 'de>(_logger: (), #[case] document: &str, #[case] expected: T) where T: Deserialize<'de> + Debug + PartialEq,73 fn attribute_ok<T, 'de>(_logger: (), #[case] document: &str, #[case] expected: T)
74 where
75 T: Deserialize<'de> + Debug + PartialEq,
76 {
77 let actual: T = from_str(document).unwrap();
78 assert_eq!(actual, expected);
79 }
80 }
81
82 mod ser {
83 use super::*;
84 use serde::{self, Serialize};
85 use serde_xml_rs::to_string;
86
87 #[derive(Serialize, Debug)]
88 #[serde(rename = "bla")]
89 struct Dummy<T> {
90 #[serde(rename = "$value")]
91 value: T,
92 }
93
94 #[rstest]
95 #[case::string("<bla>This is a String</bla>", "This is a String".to_string())]
96 #[case::string("<bla></bla>", "".to_string())]
97 #[case::string("<bla><boom/></bla>", "<boom/>".to_string())]
98 #[case::string("<bla>♫</bla>", "♫".to_string())]
99 #[case::string("<bla>♫<cookies/>♫</bla>", "♫<cookies/>♫".to_string())]
100 #[case::i64("<bla>0</bla>", 0i64)]
101 #[case::i64("<bla>-2</bla>", -2i64)]
102 #[case::i64("<bla>-1234</bla>", -1234i64)]
103 #[case::u64("<bla>0</bla>", 0u64)]
104 #[case::u64("<bla>1234</bla>", 1234u64)]
105 #[case::bool("<bla>true</bla>", true)]
106 #[case::bool("<bla>false</bla>", false)]
107 #[case::unit("<bla />", ())]
108 #[case::f64("<bla>3</bla>", 3.0f64)]
109 #[case::f64("<bla>3.1</bla>", 3.1f64)]
110 #[case::f64("<bla>-1.2</bla>", -1.2f64)]
111 #[case::f64("<bla>0.4</bla>", 0.4f64)]
112 #[case::f64("<bla>40000</bla>", 0.4e5f64)]
113 #[case::f64("<bla>400000000000000</bla>", 0.4e15f64)]
114 #[case::f64_precision_troubles("<bla>0.04</bla>", 0.4e-01f64)]
115 #[case::option("<bla></bla>", Some("".to_string()))]
116 #[case::option("<bla>42</bla>", Some("42".to_string()))]
element_ok<T>(_logger: (), #[case] expected: &str, #[case] value: T) where T: Serialize + Debug,117 fn element_ok<T>(_logger: (), #[case] expected: &str, #[case] value: T)
118 where
119 T: Serialize + Debug,
120 {
121 let actual = to_string(&Dummy { value }).unwrap();
122 assert_eq!(
123 actual,
124 format!(r#"<?xml version="1.0" encoding="UTF-8"?>{}"#, expected)
125 );
126 }
127
128 #[derive(Serialize, Debug)]
129 #[serde(rename = "bla")]
130 struct DummyAttribute<T> {
131 #[serde(rename = "@value")]
132 value: T,
133 }
134
135 #[rstest]
136 #[case::string(r#"<bla value="" />"#, "".to_string())]
137 #[case::bool(r#"<bla value="true" />"#, true)]
138 #[case::bool(r#"<bla value="false" />"#, false)]
attribute_ok<T>(_logger: (), #[case] expected: &str, #[case] value: T) where T: Serialize + Debug,139 fn attribute_ok<T>(_logger: (), #[case] expected: &str, #[case] value: T)
140 where
141 T: Serialize + Debug,
142 {
143 let actual = to_string(&DummyAttribute { value }).unwrap();
144 assert_eq!(
145 actual,
146 format!(r#"<?xml version="1.0" encoding="UTF-8"?>{}"#, expected)
147 );
148 }
149 }
150