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><boom/></bla>", "<boom/>".to_string()),
212 ("<bla>♫</bla>", "♫".to_string()),
213 ("<bla>♫</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