1 #![cfg(feature = "serialize")]
2 
3 extern crate quick_xml;
4 extern crate serde;
5 
6 use std::fmt::Debug;
7 
8 use quick_xml::de::from_str;
9 use serde::{de, ser};
10 use serde::{Deserialize, Serialize};
11 
12 #[derive(PartialEq, Debug, Serialize, Deserialize)]
13 enum Animal {
14     Dog,
15     Frog(String),
16     Ant(Simple),
17     Cat { age: usize, name: String },
18 }
19 
20 #[derive(PartialEq, Debug, Serialize, Deserialize)]
21 struct Simple {
22     a: (),
23     b: usize,
24     c: String,
25     d: Option<String>,
26 }
27 
28 #[derive(PartialEq, Debug, Serialize, Deserialize)]
29 struct Inner {
30     a: (),
31     b: (usize, String, i8),
32     c: Vec<String>,
33 }
34 
35 #[derive(PartialEq, Debug, Serialize, Deserialize)]
36 struct Outer {
37     inner: Option<Inner>,
38 }
39 
test_parse_ok<'a, T: std::fmt::Debug>(errors: &[(&'a str, T)]) where T: PartialEq + Debug + ser::Serialize + for<'de> de::Deserialize<'de>,40 fn test_parse_ok<'a, T: std::fmt::Debug>(errors: &[(&'a str, T)])
41 where
42     T: PartialEq + Debug + ser::Serialize + for<'de> de::Deserialize<'de>,
43 {
44     for (i, &(s, ref value)) in errors.iter().enumerate() {
45         match from_str::<T>(s) {
46             Ok(v) => assert_eq!(
47                 v, *value,
48                 "{} error, expected: {:?}, found: {:?}",
49                 i, value, v
50             ),
51             Err(e) => panic!("{} error, expected {:?}, found error {}", i, value, e),
52         }
53 
54         // // Make sure we can deserialize into an `Element`.
55         // let xml_value: Element = from_str(s).unwrap();
56 
57         // // Make sure we can deserialize from an `Element`.
58         // let v: T = from_value(xml_value.clone()).unwrap();
59         // assert_eq!(v, *value);
60     }
61 }
62 
test_parse_err<'a, T>(errors: &[&'a str]) where T: PartialEq + Debug + ser::Serialize + for<'de> de::Deserialize<'de>,63 fn test_parse_err<'a, T>(errors: &[&'a str])
64 where
65     T: PartialEq + Debug + ser::Serialize + for<'de> de::Deserialize<'de>,
66 {
67     for &s in errors {
68         assert!(from_str::<T>(s).is_err());
69     }
70 }
71 
test_parse_invalid<'a, T>(errors: &[&'a str]) where T: PartialEq + Debug + ser::Serialize + for<'de> de::Deserialize<'de>,72 fn test_parse_invalid<'a, T>(errors: &[&'a str])
73 where
74     T: PartialEq + Debug + ser::Serialize + for<'de> de::Deserialize<'de>,
75 {
76     for &s in errors {
77         assert!(from_str::<T>(s).is_err());
78     }
79 }
80 
81 #[test]
test_namespaces()82 fn test_namespaces() {
83     #[derive(PartialEq, Serialize, Deserialize, Debug)]
84     struct Envelope {
85         subject: String,
86     }
87     let s = r#"
88     <?xml version="1.0" encoding="UTF-8"?>
89     <gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
90         <gesmes:subject>Reference rates</gesmes:subject>
91     </gesmes:Envelope>"#;
92     test_parse_ok(&[(
93         s,
94         Envelope {
95             subject: "Reference rates".to_string(),
96         },
97     )]);
98 }
99 
100 #[test]
101 #[ignore] // FIXME
test_doctype()102 fn test_doctype() {
103     #[derive(PartialEq, Serialize, Deserialize, Debug)]
104     struct Envelope {
105         subject: String,
106     }
107 
108     test_parse_ok(&[
109         (
110             r#"
111             <?xml version="1.0" encoding="UTF-8"?>
112             <!DOCTYPE Envelope>
113             <Envelope>
114             <subject>Reference rates</subject>
115             </Envelope>"#,
116             Envelope {
117                 subject: "Reference rates".to_string(),
118             },
119         ),
120         (
121             r#"
122             <?xml version="1.0" encoding="UTF-8"?>
123             <!DOCTYPE Envelope[]>
124             <Envelope>
125             <subject>Reference rates</subject>
126             </Envelope>"#,
127             Envelope {
128                 subject: "Reference rates".to_string(),
129             },
130         ),
131         (
132             r#"
133             <?xml version="1.0" encoding="UTF-8"?>
134             <!DOCTYPE Envelope [
135                 <!ELEMENT subject (#PCDATA)>
136             ] >
137             <Envelope>
138             <subject>Reference rates</subject>
139             </Envelope>"#,
140             Envelope {
141                 subject: "Reference rates".to_string(),
142             },
143         ),
144     ]);
145 }
146 
147 // pass in quick-xml because there is no proper doctype support
148 //
149 //
150 // #[test]
151 // fn test_doctype_fail() {
152 //     #[derive(PartialEq, Serialize, Deserialize, Debug)]
153 //     struct Envelope {
154 //         subject: String,
155 //     }
156 //
157 //     test_parse_err::<Envelope>(&[
158 //         r#"
159 //             <?xml version="1.0" encoding="UTF-8"?>
160 //             <!DOCTYPE Envelope [
161 //                 <!ELEMENT subject (#PCDATA)>
162 //             >
163 //             <Envelope>
164 //             <subject>Reference rates</subject>
165 //             </Envelope>"#,
166 //         r#"
167 //             <?xml version="1.0" encoding="UTF-8"?>
168 //             <Envelope>
169 //             <subject>Reference rates</subject>
170 //             <!DOCTYPE Envelope [
171 //                 <!ELEMENT subject (#PCDATA)>
172 //             ]>
173 //             </Envelope>"#,
174 //     ])
175 // }
176 
177 #[test]
178 #[ignore] // FIXME
test_forwarded_namespace()179 fn test_forwarded_namespace() {
180     #[derive(PartialEq, Serialize, Deserialize, Debug)]
181     struct Graphml {
182         #[serde(rename = "xsi:schemaLocation")]
183         schema_location: String,
184     }
185     let s = r#"
186     <?xml version="1.0" encoding="UTF-8"?>
187     <graphml xmlns="http://graphml.graphdrawing.org/xmlns"
188         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
189         xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
190         http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
191     </graphml>"#;
192     test_parse_ok(&[(
193         s,
194         Graphml {
195             schema_location: "http://graphml.graphdrawing.org/xmlns
196         http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"
197                 .to_string(),
198         },
199     )]);
200 }
201 
202 #[test]
test_parse_string()203 fn test_parse_string() {
204     test_parse_ok(&[
205         (
206             "<bla>This is a String</bla>",
207             "This is a String".to_string(),
208         ),
209         ("<bla></bla>", "".to_string()),
210         ("<bla>     </bla>", "".to_string()),
211         ("<bla>&lt;boom/&gt;</bla>", "<boom/>".to_string()),
212         ("<bla>&#9835;</bla>", "♫".to_string()),
213         ("<bla>&#x266B;</bla>", "♫".to_string()),
214         //(
215         //    "<bla>♫<![CDATA[<cookies/>]]>♫</bla>",
216         //    "♫<cookies/>♫".to_string(),
217         //),
218     ]);
219 }
220 
221 #[test]
222 #[ignore] // FIXME
test_parse_string_not_trim()223 fn test_parse_string_not_trim() {
224     test_parse_ok(&[("<bla>     </bla>", "     ".to_string())]);
225 }
226 
227 #[test]
228 #[ignore] // FIXME
test_parse_enum()229 fn test_parse_enum() {
230     use self::Animal::*;
231 
232     test_parse_ok(&[
233         ("<Animal xsi:type=\"Dog\"/>", Dog),
234         (
235             "<Animal xsi:type=\"Frog\">Quak</Animal>",
236             Frog("Quak".to_string()),
237         ),
238         (
239             "<Animal xsi:type=\"Ant\"><a/><c>bla</c><b>15</b><d>Foo</d></Animal>",
240             Ant(Simple {
241                 a: (),
242                 b: 15,
243                 c: "bla".to_string(),
244                 d: Some("Foo".to_string()),
245             }),
246         ),
247         (
248             "<Animal xsi:type=\"Ant\"><a/><c>bla</c><b>15</b></Animal>",
249             Ant(Simple {
250                 a: (),
251                 b: 15,
252                 c: "bla".to_string(),
253                 d: None,
254             }),
255         ),
256         (
257             "<Animal xsi:type=\"Cat\"><age>42</age><name>Shere Khan</name></Animal>",
258             Cat {
259                 age: 42,
260                 name: "Shere Khan".to_string(),
261             },
262         ),
263     ]);
264 
265     #[derive(PartialEq, Debug, Serialize, Deserialize)]
266     struct Helper {
267         x: Animal,
268     }
269 
270     test_parse_ok(&[
271         ("<Helper><x xsi:type=\"Dog\"/></Helper>", Helper { x: Dog }),
272         (
273             "<Helper><x xsi:type=\"Frog\">Quak</Animal></Helper>",
274             Helper {
275                 x: Frog("Quak".to_string()),
276             },
277         ),
278         (
279             "<Helper><x xsi:type=\"Cat\">
280                 <age>42</age>
281                 <name>Shere Khan</name>
282             </x></Helper>",
283             Helper {
284                 x: Cat {
285                     age: 42,
286                     name: "Shere Khan".to_string(),
287                 },
288             },
289         ),
290     ]);
291 }
292 
293 #[test]
test_parse_i64()294 fn test_parse_i64() {
295     test_parse_ok(&[
296         ("<bla>0</bla>", 0),
297         ("<bla>-2</bla>", -2),
298         ("<bla>-1234</bla>", -1234),
299         ("<bla> -1234 </bla>", -1234),
300     ]);
301 }
302 
303 #[test]
test_parse_u64()304 fn test_parse_u64() {
305     test_parse_ok(&[
306         ("<bla>0</bla>", 0),
307         ("<bla>1234</bla>", 1234),
308         ("<bla> 1234 </bla>", 1234),
309     ]);
310 }
311 
312 #[test]
test_parse_bool()313 fn test_parse_bool() {
314     test_parse_ok(&[
315         ("<bla>true</bla>", true),
316         ("<bla>false</bla>", false),
317         ("<bla> true </bla>", true),
318         ("<bla> false </bla>", false),
319         ("<bla>1</bla>", true),
320         ("<bla>0</bla>", false),
321     ]);
322 
323     test_parse_invalid::<bool>(&["<bla>verum</bla>"]);
324 }
325 
326 #[test]
test_parse_unit()327 fn test_parse_unit() {
328     test_parse_ok(&[("<bla/>", ())]);
329 }
330 
331 #[test]
test_parse_f64()332 fn test_parse_f64() {
333     test_parse_ok(&[
334         ("<bla>3.0</bla>", 3.0f64),
335         ("<bla>3.1</bla>", 3.1),
336         ("<bla>-1.2</bla>", -1.2),
337         ("<bla>0.4</bla>", 0.4),
338         ("<bla>0.4e5</bla>", 0.4e5),
339         ("<bla>0.4e15</bla>", 0.4e15),
340         ("<bla>0.4e-01</bla>", 0.4e-01), // precision troubles
341         ("<bla> 0.4e-01 </bla>", 0.4e-01),
342     ]);
343 }
344 
345 #[test]
test_parse_struct()346 fn test_parse_struct() {
347     test_parse_ok(&[
348         (
349             "<Simple>
350                 <c>abc</c>
351                 <a/>
352                 <b>2</b>
353             </Simple>",
354             Simple {
355                 a: (),
356                 b: 2,
357                 c: "abc".to_string(),
358                 d: None,
359             },
360         ),
361         (
362             "<Simple><!-- this is a comment -->
363                 <c>abc</c>
364                 <a/>
365                 <b>2</b>
366             </Simple>",
367             Simple {
368                 a: (),
369                 b: 2,
370                 c: "abc".to_string(),
371                 d: None,
372             },
373         ),
374         (
375             "<Simple d=\"Foo\"><!-- this is a comment -->
376                 <c>abc</c>
377                 <a/>
378                 <b>2</b>
379             </Simple>",
380             Simple {
381                 a: (),
382                 b: 2,
383                 c: "abc".to_string(),
384                 d: Some("Foo".to_string()),
385             },
386         ),
387     ]);
388 }
389 
390 #[test]
test_option()391 fn test_option() {
392     test_parse_ok(&[
393         ("<a/>", Some("".to_string())),
394         ("<a></a>", Some("".to_string())),
395         ("<a> </a>", Some("".to_string())),
396         ("<a>42</a>", Some("42".to_string())),
397     ]);
398 }
399 
400 #[test]
401 #[ignore] // FIXME
test_option_not_trim()402 fn test_option_not_trim() {
403     test_parse_ok(&[("<a> </a>", Some(" ".to_string()))]);
404 }
405 
406 #[test]
test_amoskvin()407 fn test_amoskvin() {
408     #[derive(Debug, Deserialize, PartialEq, Serialize)]
409     struct Root {
410         foo: Vec<Foo>,
411     }
412 
413     #[derive(Debug, Deserialize, PartialEq, Serialize)]
414     struct Foo {
415         a: String,
416         b: Option<String>,
417     }
418     test_parse_ok(&[(
419         "
420 <root>
421 <foo>
422  <a>Hello</a>
423  <b>World</b>
424 </foo>
425 <foo>
426  <a>Hi</a>
427 </foo>
428 </root>",
429         Root {
430             foo: vec![
431                 Foo {
432                     a: "Hello".to_string(),
433                     b: Some("World".to_string()),
434                 },
435                 Foo {
436                     a: "Hi".to_string(),
437                     b: None,
438                 },
439             ],
440         },
441     )]);
442 }
443 
444 #[test]
445 #[ignore] // FIXME
test_nicolai86()446 fn test_nicolai86() {
447     #[derive(Serialize, Deserialize, PartialEq, Debug)]
448     struct TheSender {
449         name: String,
450     }
451 
452     #[derive(Serialize, Deserialize, PartialEq, Debug)]
453     struct CurrencyCube {
454         currency: String,
455         rate: String,
456     }
457 
458     #[derive(Serialize, Deserialize, PartialEq, Debug)]
459     #[allow(non_snake_case)]
460     struct InnerCube {
461         Cube: Vec<CurrencyCube>,
462     }
463 
464     #[derive(Serialize, Deserialize, PartialEq, Debug)]
465     #[allow(non_snake_case)]
466     struct OuterCube {
467         Cube: Vec<InnerCube>,
468     }
469 
470     #[derive(Serialize, Deserialize, PartialEq, Debug)]
471     #[allow(non_snake_case)]
472     struct Envelope {
473         subject: String,
474         Sender: TheSender,
475         Cube: OuterCube,
476     }
477     test_parse_ok(&[
478         (
479             r#"
480             <?xml version="1.0" encoding="UTF-8"?>
481             <gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
482                 <gesmes:subject>Reference rates</gesmes:subject>
483                 <gesmes:Sender>
484                     <gesmes:name>European Central Bank</gesmes:name>
485                 </gesmes:Sender>
486                 <Cube> </Cube>
487             </gesmes:Envelope>"#,
488             Envelope {
489                 subject: "Reference rates".to_string(),
490                 Sender: TheSender {
491                     name: "European Central Bank".to_string(),
492                 },
493                 Cube: OuterCube { Cube: vec![] },
494             },
495         ),
496         (
497             r#"
498             <?xml version="1.0" encoding="UTF-8"?>
499             <gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
500                 <gesmes:subject>Reference rates</gesmes:subject>
501                 <gesmes:Sender>
502                     <gesmes:name>European Central Bank</gesmes:name>
503                 </gesmes:Sender>
504                 <Cube><Cube>
505                     <Cube currency='GBP' rate='0.81725'/>
506                     <Cube currency='Latinum' rate='999999'/>
507                 </Cube></Cube>
508             </gesmes:Envelope>"#,
509             Envelope {
510                 subject: "Reference rates".to_string(),
511                 Sender: TheSender {
512                     name: "European Central Bank".to_string(),
513                 },
514                 Cube: OuterCube {
515                     Cube: vec![InnerCube {
516                         Cube: vec![
517                             CurrencyCube {
518                                 currency: "GBP".to_string(),
519                                 rate: "0.81725".to_string(),
520                             },
521                             CurrencyCube {
522                                 currency: "Latinum".to_string(),
523                                 rate: "999999".to_string(),
524                             },
525                         ],
526                     }],
527                 },
528             },
529         ),
530     ]);
531 }
532 
533 #[test]
test_hugo_duncan2()534 fn test_hugo_duncan2() {
535     let s = r#"
536     <?xml version="1.0" encoding="UTF-8"?>
537     <DescribeVpcsResponse xmlns="http://ec2.amazonaws.com/doc/2014-10-01/">
538         <requestId>8d521e9a-509e-4ef6-bbb7-9f1ac0d49cd1</requestId>
539         <vpcSet>
540             <item>
541                 <vpcId>vpc-ba0d18d8</vpcId>
542                 <state>available</state>
543             </item>
544         </vpcSet>
545     </DescribeVpcsResponse>"#;
546     #[derive(PartialEq, Debug, Serialize, Deserialize)]
547     #[allow(non_snake_case)]
548     struct VpcSet {
549         vpcId: String,
550         state: String,
551     }
552 
553     #[derive(PartialEq, Debug, Serialize)]
554     struct ItemVec<T>(Vec<T>);
555 
556     impl<'de, T: de::Deserialize<'de>> de::Deserialize<'de> for ItemVec<T> {
557         fn deserialize<D>(deserializer: D) -> Result<ItemVec<T>, D::Error>
558         where
559             D: de::Deserializer<'de>,
560         {
561             #[derive(PartialEq, Debug, Serialize, Deserialize)]
562             struct Helper<U> {
563                 item: Vec<U>,
564             }
565             let h: Helper<_> = de::Deserialize::deserialize(deserializer)?;
566             Ok(ItemVec(h.item))
567         }
568     }
569     #[derive(PartialEq, Debug, Serialize, Deserialize)]
570     #[allow(non_snake_case)]
571     struct DescribeVpcsResponse {
572         requestId: String,
573         vpcSet: ItemVec<VpcSet>,
574     }
575     test_parse_ok(&[(
576         s,
577         DescribeVpcsResponse {
578             requestId: "8d521e9a-509e-4ef6-bbb7-9f1ac0d49cd1".to_string(),
579             vpcSet: ItemVec(vec![VpcSet {
580                 vpcId: "vpc-ba0d18d8".to_string(),
581                 state: "available".to_string(),
582             }]),
583         },
584     )]);
585 }
586 
587 #[test]
test_hugo_duncan()588 fn test_hugo_duncan() {
589     let s = "
590         <?xml version=\"1.0\" encoding=\"UTF-8\"?>
591         <DescribeInstancesResponse xmlns=\"http://ec2.amazonaws.com/doc/2014-10-01/\">
592             <requestId>9474f558-10a5-42e8-84d1-f9ee181fe943</requestId>
593             <reservationSet/>
594         </DescribeInstancesResponse>
595     ";
596     #[derive(PartialEq, Debug, Serialize, Deserialize)]
597     #[allow(non_snake_case)]
598     struct DescribeInstancesResponse {
599         requestId: String,
600         reservationSet: (),
601     }
602     test_parse_ok(&[(
603         s,
604         DescribeInstancesResponse {
605             requestId: "9474f558-10a5-42e8-84d1-f9ee181fe943".to_string(),
606             reservationSet: (),
607         },
608     )]);
609 }
610 
611 #[test]
test_parse_xml_value()612 fn test_parse_xml_value() {
613     #[derive(Eq, Debug, PartialEq, Deserialize, Serialize)]
614     struct Test {
615         #[serde(rename = "$value")]
616         myval: String,
617     }
618     test_parse_ok(&[(
619         "<Test>abc</Test>",
620         Test {
621             myval: "abc".to_string(),
622         },
623     )]);
624 }
625 
626 #[test]
627 #[ignore] // FIXME
test_parse_complexstruct()628 fn test_parse_complexstruct() {
629     test_parse_ok(&[
630         (
631             "<Outer>
632                 <inner>
633                     <b>2</b>
634                     <b>boom</b>
635                     <b>88</b>
636                 </inner>
637             </Outer>",
638             Outer {
639                 inner: Some(Inner {
640                     a: (),
641                     b: (2, "boom".to_string(), 88),
642                     c: vec![],
643                 }),
644             },
645         ),
646         (
647             "<Outer>
648                 <inner>
649                     <c>abc</c>
650                     <c>xyz</c>
651                     <a/>
652                     <b>2</b>
653                     <b>boom</b>
654                     <b>88</b>
655                 </inner>
656             </Outer>",
657             Outer {
658                 inner: Some(Inner {
659                     a: (),
660                     b: (2, "boom".to_string(), 88),
661                     c: vec!["abc".to_string(), "xyz".to_string()],
662                 }),
663             },
664         ),
665         ("<Outer/>", Outer { inner: None }),
666     ]);
667 }
668 
669 #[test]
test_parse_attributes()670 fn test_parse_attributes() {
671     #[derive(PartialEq, Debug, Serialize, Deserialize)]
672     struct A {
673         a1: String,
674         #[serde(rename = "$value")]
675         a2: i32,
676     }
677 
678     test_parse_ok(&[(
679         r#"<A a1="What is the answer to the ultimate question?">42</A>"#,
680         A {
681             a1: "What is the answer to the ultimate question?".to_string(),
682             a2: 42,
683         },
684     )]);
685 
686     #[derive(PartialEq, Debug, Serialize, Deserialize)]
687     struct B {
688         b1: String,
689         b2: i32,
690     }
691 
692     test_parse_ok(&[(
693         r#"<B b1="What is the answer to the ultimate question?" b2="42"/>"#,
694         B {
695             b1: "What is the answer to the ultimate question?".to_string(),
696             b2: 42,
697         },
698     )]);
699 
700     #[derive(PartialEq, Debug, Serialize, Deserialize)]
701     struct C {
702         c1: B,
703     }
704 
705     test_parse_ok(&[
706         (
707             r#"<C><c1 b1="What is the answer to the ultimate question?" b2="42"/></C>"#,
708             C {
709                 c1: B {
710                     b1: "What is the answer to the ultimate question?".to_string(),
711                     b2: 42,
712                 },
713             },
714         ),
715         (
716             r#"<C><c1 b1="What is the answer to the ultimate question?" b2="42"/> </C>"#,
717             C {
718                 c1: B {
719                     b1: "What is the answer to the ultimate question?".to_string(),
720                     b2: 42,
721                 },
722             },
723         ),
724         (
725             r#"<C>  <c1 b1="What is the answer to the ultimate question?" b2="42">
726         </c1> </C>"#,
727             C {
728                 c1: B {
729                     b1: "What is the answer to the ultimate question?".to_string(),
730                     b2: 42,
731                 },
732             },
733         ),
734     ]);
735 
736     #[derive(PartialEq, Debug, Serialize, Deserialize)]
737     struct D {
738         d1: Option<A>,
739     }
740     test_parse_ok(&[(
741         r#"<D><d1 a1="What is the answer to the ultimate question?">42</d1></D>"#,
742         D {
743             d1: Some(A {
744                 a1: "What is the answer to the ultimate question?".to_string(),
745                 a2: 42,
746             }),
747         },
748     )]);
749 }
750 
751 #[test]
752 #[ignore] // FIXME
test_parse_hierarchies()753 fn test_parse_hierarchies() {
754     #[derive(PartialEq, Debug, Serialize, Deserialize)]
755     struct A {
756         a1: String,
757         a2: (String, String),
758     }
759     #[derive(PartialEq, Debug, Serialize, Deserialize)]
760     struct B {
761         b1: A,
762         b2: (A, A),
763     }
764     #[derive(PartialEq, Debug, Serialize, Deserialize)]
765     struct C {
766         c1: B,
767         c2: Vec<B>,
768     }
769 
770     test_parse_ok(&[
771         (
772             "<C><c1>
773             <b1>
774                 <a1>No</a1>
775                 <a2>Maybe</a2>
776                 <a2>Yes</a2>
777             </b1>
778             <b2>
779                 <a1>Red</a1>
780                 <a2>Green</a2>
781                 <a2>Blue</a2>
782             </b2>
783             <b2>
784                 <a1>London</a1>
785                 <a2>Berlin</a2>
786                 <a2>Paris</a2>
787             </b2>
788         </c1></C>",
789             C {
790                 c1: B {
791                     b1: A {
792                         a1: "No".to_string(),
793                         a2: ("Maybe".to_string(), "Yes".to_string()),
794                     },
795                     b2: (
796                         A {
797                             a1: "Red".to_string(),
798                             a2: ("Green".to_string(), "Blue".to_string()),
799                         },
800                         A {
801                             a1: "London".to_string(),
802                             a2: ("Berlin".to_string(), "Paris".to_string()),
803                         },
804                     ),
805                 },
806                 c2: vec![],
807             },
808         ),
809         (
810             "<C><c1>
811             <b2>
812                 <a2>Green</a2>
813                 <a2>Blue</a2>
814                 <a1>Red</a1>
815             </b2>
816             <b2>
817                 <a2>Berlin</a2>
818                 <a2>Paris</a2>
819                 <a1>London</a1>
820             </b2>
821             <b1>
822                 <a2>Maybe</a2>
823                 <a2>Yes</a2>
824                 <a1>No</a1>
825             </b1>
826         </c1></C>",
827             C {
828                 c1: B {
829                     b1: A {
830                         a1: "No".to_string(),
831                         a2: ("Maybe".to_string(), "Yes".to_string()),
832                     },
833                     b2: (
834                         A {
835                             a1: "Red".to_string(),
836                             a2: ("Green".to_string(), "Blue".to_string()),
837                         },
838                         A {
839                             a1: "London".to_string(),
840                             a2: ("Berlin".to_string(), "Paris".to_string()),
841                         },
842                     ),
843                 },
844                 c2: vec![],
845             },
846         ),
847     ]);
848 }
849 
850 #[test]
unknown_field()851 fn unknown_field() {
852     #[derive(Deserialize, Debug, PartialEq, Eq, Serialize)]
853     struct A {
854         other: Vec<Other>,
855     }
856 
857     #[derive(Deserialize, Debug, PartialEq, Eq, Serialize)]
858     struct Other {
859         d: i32,
860     }
861     test_parse_ok(&[(
862         "<a>
863                <b>
864                  <c>5</c>
865                </b>
866                <other>
867                  <d>6</d>
868                </other>
869             </a>",
870         A {
871             other: vec![Other { d: 6 }],
872         },
873     )]);
874 }
875 
876 // #[test]
877 // fn eoz() {
878 //     use std::io::Read;
879 //     let mut file = std::fs::File::open("Report_test.2.xml").unwrap();
880 //     let mut s = String::new();
881 //     file.read_to_string(&mut s).unwrap();
882 
883 //     let _xml_value: Element = from_str(&s).unwrap();
884 // }
885 
886 #[test]
test_parse_unfinished()887 fn test_parse_unfinished() {
888     test_parse_err::<Simple>(&["<Simple>
889             <c>abc</c>
890             <a/>
891             <b>2</b>
892             <d/>"]);
893 }
894 
895 #[test]
test_things_qc_found()896 fn test_things_qc_found() {
897     test_parse_err::<u32>(&["<\u{0}:/"]);
898 }
899 
900 #[test]
futile()901 fn futile() {
902     #[derive(Eq, PartialEq, Debug, Serialize, Deserialize)]
903     struct Object {
904         id: u8,
905         name: String,
906         x: u8,
907         y: u8,
908         width: u8,
909         height: u8,
910         ellipse: Option<()>,
911     }
912 
913     test_parse_ok(&[
914         (
915             r###"
916             <object id="11" name="testEllipse" x="102" y="38" width="21" height="14">
917               <ellipse/>
918             </object>
919             "###,
920             Object {
921                 id: 11,
922                 name: "testEllipse".to_owned(),
923                 x: 102,
924                 y: 38,
925                 width: 21,
926                 height: 14,
927                 ellipse: Some(()),
928             },
929         ),
930         (
931             r###"
932             <object id="11" name="testEllipse" x="102" y="38" width="21" height="14">
933             </object>
934             "###,
935             Object {
936                 id: 11,
937                 name: "testEllipse".to_owned(),
938                 x: 102,
939                 y: 38,
940                 width: 21,
941                 height: 14,
942                 ellipse: None,
943             },
944         ),
945     ]);
946 }
947 
948 #[test]
futile2()949 fn futile2() {
950     #[derive(Eq, PartialEq, Debug, Serialize, Deserialize)]
951     struct Null;
952 
953     #[derive(Eq, PartialEq, Debug, Serialize, Deserialize)]
954     struct Object {
955         field: Option<Null>,
956     };
957 
958     #[derive(Eq, PartialEq, Debug, Serialize, Deserialize)]
959     struct Stuff {
960         stuff_field: Option<Object>,
961     };
962 
963     test_parse_ok(&[
964         (
965             r###"
966             <object>
967               <field/>
968             </object>
969             "###,
970             Object { field: Some(Null) },
971         ),
972         (
973             r###"
974             <object>
975             </object>
976             "###,
977             Object { field: None },
978         ),
979     ]);
980 
981     test_parse_ok(&[
982         (
983             r###"
984             <object>
985               <stuff_field/>
986             </object>
987             "###,
988             Stuff {
989                 stuff_field: Some(Object { field: None }),
990             },
991         ),
992         (
993             r###"
994             <object>
995               <stuff_field>
996                 <field/>
997               </stuff_field>
998             </object>
999             "###,
1000             Stuff {
1001                 stuff_field: Some(Object { field: Some(Null) }),
1002             },
1003         ),
1004         (
1005             r###"
1006             <object>
1007             </object>
1008             "###,
1009             Stuff { stuff_field: None },
1010         ),
1011         (
1012             r###"
1013             <object/>
1014             "###,
1015             Stuff { stuff_field: None },
1016         ),
1017     ]);
1018 }
1019