1 extern crate quick_xml;
2 #[cfg(feature = "serialize")]
3 extern crate serde;
4 
5 use quick_xml::events::attributes::Attribute;
6 use quick_xml::events::Event::*;
7 use quick_xml::Reader;
8 use std::borrow::Cow;
9 use std::io::Cursor;
10 
11 #[cfg(feature = "serialize")]
12 use serde::{Deserialize, Serialize};
13 
14 #[test]
test_sample()15 fn test_sample() {
16     let src: &[u8] = include_bytes!("sample_rss.xml");
17     let mut buf = Vec::new();
18     let mut r = Reader::from_reader(src);
19     let mut count = 0;
20     loop {
21         match r.read_event(&mut buf).unwrap() {
22             Start(_) => count += 1,
23             Decl(e) => println!("{:?}", e.version()),
24             Eof => break,
25             _ => (),
26         }
27         buf.clear();
28     }
29     println!("{}", count);
30 }
31 
32 #[test]
test_attributes_empty()33 fn test_attributes_empty() {
34     let src = b"<a att1='a' att2='b'/>";
35     let mut r = Reader::from_reader(src as &[u8]);
36     r.trim_text(true).expand_empty_elements(false);
37     let mut buf = Vec::new();
38     match r.read_event(&mut buf) {
39         Ok(Empty(e)) => {
40             let mut atts = e.attributes();
41             match atts.next() {
42                 Some(Ok(Attribute {
43                     key: b"att1",
44                     value: Cow::Borrowed(b"a"),
45                 })) => (),
46                 e => panic!("Expecting att1='a' attribute, found {:?}", e),
47             }
48             match atts.next() {
49                 Some(Ok(Attribute {
50                     key: b"att2",
51                     value: Cow::Borrowed(b"b"),
52                 })) => (),
53                 e => panic!("Expecting att2='b' attribute, found {:?}", e),
54             }
55             match atts.next() {
56                 None => (),
57                 e => panic!("Expecting None, found {:?}", e),
58             }
59         }
60         e => panic!("Expecting Empty event, got {:?}", e),
61     }
62 }
63 
64 #[test]
test_attribute_equal()65 fn test_attribute_equal() {
66     let src = b"<a att1=\"a=b\"/>";
67     let mut r = Reader::from_reader(src as &[u8]);
68     r.trim_text(true).expand_empty_elements(false);
69     let mut buf = Vec::new();
70     match r.read_event(&mut buf) {
71         Ok(Empty(e)) => {
72             let mut atts = e.attributes();
73             match atts.next() {
74                 Some(Ok(Attribute {
75                     key: b"att1",
76                     value: Cow::Borrowed(b"a=b"),
77                 })) => (),
78                 e => panic!("Expecting att1=\"a=b\" attribute, found {:?}", e),
79             }
80             match atts.next() {
81                 None => (),
82                 e => panic!("Expecting None, found {:?}", e),
83             }
84         }
85         e => panic!("Expecting Empty event, got {:?}", e),
86     }
87 }
88 
89 #[test]
test_comment_starting_with_gt()90 fn test_comment_starting_with_gt() {
91     let src = b"<a /><!-->-->";
92     let mut r = Reader::from_reader(src as &[u8]);
93     r.trim_text(true).expand_empty_elements(false);
94     let mut buf = Vec::new();
95     loop {
96         match r.read_event(&mut buf) {
97             Ok(Comment(ref e)) if &**e == b">" => break,
98             Ok(Eof) => panic!("Expecting Comment"),
99             _ => (),
100         }
101     }
102 }
103 
104 /// Single empty element with qualified attributes.
105 /// Empty element expansion: disabled
106 /// The code path for namespace handling is slightly different for `Empty` vs. `Start+End`.
107 #[test]
test_attributes_empty_ns()108 fn test_attributes_empty_ns() {
109     let src = b"<a att1='a' r:att2='b' xmlns:r='urn:example:r' />";
110 
111     let mut r = Reader::from_reader(src as &[u8]);
112     r.trim_text(true).expand_empty_elements(false);
113     let mut buf = Vec::new();
114     let mut ns_buf = Vec::new();
115 
116     let e = match r.read_namespaced_event(&mut buf, &mut ns_buf) {
117         Ok((None, Empty(e))) => e,
118         e => panic!("Expecting Empty event, got {:?}", e),
119     };
120 
121     let mut atts = e
122         .attributes()
123         .map(|ar| ar.expect("Expecting attribute parsing to succeed."))
124         // we don't care about xmlns attributes for this test
125         .filter(|kv| !kv.key.starts_with(b"xmlns"))
126         .map(|Attribute { key: name, value }| {
127             let (opt_ns, local_name) = r.attribute_namespace(name, &ns_buf);
128             (opt_ns, local_name, value)
129         });
130     match atts.next() {
131         Some((None, b"att1", Cow::Borrowed(b"a"))) => (),
132         e => panic!("Expecting att1='a' attribute, found {:?}", e),
133     }
134     match atts.next() {
135         Some((Some(ns), b"att2", Cow::Borrowed(b"b"))) => {
136             assert_eq!(&ns[..], b"urn:example:r");
137         }
138         e => panic!(
139             "Expecting {{urn:example:r}}att2='b' attribute, found {:?}",
140             e
141         ),
142     }
143     match atts.next() {
144         None => (),
145         e => panic!("Expecting None, found {:?}", e),
146     }
147 }
148 
149 /// Single empty element with qualified attributes.
150 /// Empty element expansion: enabled
151 /// The code path for namespace handling is slightly different for `Empty` vs. `Start+End`.
152 #[test]
test_attributes_empty_ns_expanded()153 fn test_attributes_empty_ns_expanded() {
154     let src = b"<a att1='a' r:att2='b' xmlns:r='urn:example:r' />";
155 
156     let mut r = Reader::from_reader(src as &[u8]);
157     r.trim_text(true).expand_empty_elements(true);
158     let mut buf = Vec::new();
159     let mut ns_buf = Vec::new();
160     {
161         let e = match r.read_namespaced_event(&mut buf, &mut ns_buf) {
162             Ok((None, Start(e))) => e,
163             e => panic!("Expecting Empty event, got {:?}", e),
164         };
165 
166         let mut atts = e
167             .attributes()
168             .map(|ar| ar.expect("Expecting attribute parsing to succeed."))
169             // we don't care about xmlns attributes for this test
170             .filter(|kv| !kv.key.starts_with(b"xmlns"))
171             .map(|Attribute { key: name, value }| {
172                 let (opt_ns, local_name) = r.attribute_namespace(name, &ns_buf);
173                 (opt_ns, local_name, value)
174             });
175         match atts.next() {
176             Some((None, b"att1", Cow::Borrowed(b"a"))) => (),
177             e => panic!("Expecting att1='a' attribute, found {:?}", e),
178         }
179         match atts.next() {
180             Some((Some(ns), b"att2", Cow::Borrowed(b"b"))) => {
181                 assert_eq!(&ns[..], b"urn:example:r");
182             }
183             e => panic!(
184                 "Expecting {{urn:example:r}}att2='b' attribute, found {:?}",
185                 e
186             ),
187         }
188         match atts.next() {
189             None => (),
190             e => panic!("Expecting None, found {:?}", e),
191         }
192     }
193 
194     match r.read_namespaced_event(&mut buf, &mut ns_buf) {
195         Ok((None, End(e))) => assert_eq!(b"a", e.name()),
196         e => panic!("Expecting End event, got {:?}", e),
197     }
198 }
199 
200 #[test]
test_default_ns_shadowing_empty()201 fn test_default_ns_shadowing_empty() {
202     let src = b"<e xmlns='urn:example:o'><e att1='a' xmlns='urn:example:i' /></e>";
203 
204     let mut r = Reader::from_reader(src as &[u8]);
205     r.trim_text(true).expand_empty_elements(false);
206     let mut buf = Vec::new();
207     let mut ns_buf = Vec::new();
208 
209     // <outer xmlns='urn:example:o'>
210     {
211         match r.read_namespaced_event(&mut buf, &mut ns_buf) {
212             Ok((Some(ns), Start(e))) => {
213                 assert_eq!(&ns[..], b"urn:example:o");
214                 assert_eq!(e.name(), b"e");
215             }
216             e => panic!("Expected Start event (<outer>), got {:?}", e),
217         }
218     }
219 
220     // <inner att1='a' xmlns='urn:example:i' />
221     {
222         let e = match r.read_namespaced_event(&mut buf, &mut ns_buf) {
223             Ok((Some(ns), Empty(e))) => {
224                 assert_eq!(::std::str::from_utf8(ns).unwrap(), "urn:example:i");
225                 assert_eq!(e.name(), b"e");
226                 e
227             }
228             e => panic!("Expecting Empty event, got {:?}", e),
229         };
230 
231         let mut atts = e
232             .attributes()
233             .map(|ar| ar.expect("Expecting attribute parsing to succeed."))
234             // we don't care about xmlns attributes for this test
235             .filter(|kv| !kv.key.starts_with(b"xmlns"))
236             .map(|Attribute { key: name, value }| {
237                 let (opt_ns, local_name) = r.attribute_namespace(name, &ns_buf);
238                 (opt_ns, local_name, value)
239             });
240         // the attribute should _not_ have a namespace name. The default namespace does not
241         // apply to attributes.
242         match atts.next() {
243             Some((None, b"att1", Cow::Borrowed(b"a"))) => (),
244             e => panic!("Expecting att1='a' attribute, found {:?}", e),
245         }
246         match atts.next() {
247             None => (),
248             e => panic!("Expecting None, found {:?}", e),
249         }
250     }
251 
252     // </outer>
253     match r.read_namespaced_event(&mut buf, &mut ns_buf) {
254         Ok((Some(ns), End(e))) => {
255             assert_eq!(&ns[..], b"urn:example:o");
256             assert_eq!(e.name(), b"e");
257         }
258         e => panic!("Expected End event (<outer>), got {:?}", e),
259     }
260 }
261 
262 #[test]
test_default_ns_shadowing_expanded()263 fn test_default_ns_shadowing_expanded() {
264     let src = b"<e xmlns='urn:example:o'><e att1='a' xmlns='urn:example:i' /></e>";
265 
266     let mut r = Reader::from_reader(src as &[u8]);
267     r.trim_text(true).expand_empty_elements(true);
268     let mut buf = Vec::new();
269     let mut ns_buf = Vec::new();
270 
271     // <outer xmlns='urn:example:o'>
272     {
273         match r.read_namespaced_event(&mut buf, &mut ns_buf) {
274             Ok((Some(ns), Start(e))) => {
275                 assert_eq!(&ns[..], b"urn:example:o");
276                 assert_eq!(e.name(), b"e");
277             }
278             e => panic!("Expected Start event (<outer>), got {:?}", e),
279         }
280     }
281     buf.clear();
282 
283     // <inner att1='a' xmlns='urn:example:i' />
284     {
285         let e = match r.read_namespaced_event(&mut buf, &mut ns_buf) {
286             Ok((Some(ns), Start(e))) => {
287                 assert_eq!(&ns[..], b"urn:example:i");
288                 assert_eq!(e.name(), b"e");
289                 e
290             }
291             e => panic!("Expecting Start event (<inner>), got {:?}", e),
292         };
293         let mut atts = e
294             .attributes()
295             .map(|ar| ar.expect("Expecting attribute parsing to succeed."))
296             // we don't care about xmlns attributes for this test
297             .filter(|kv| !kv.key.starts_with(b"xmlns"))
298             .map(|Attribute { key: name, value }| {
299                 let (opt_ns, local_name) = r.attribute_namespace(name, &ns_buf);
300                 (opt_ns, local_name, value)
301             });
302         // the attribute should _not_ have a namespace name. The default namespace does not
303         // apply to attributes.
304         match atts.next() {
305             Some((None, b"att1", Cow::Borrowed(b"a"))) => (),
306             e => panic!("Expecting att1='a' attribute, found {:?}", e),
307         }
308         match atts.next() {
309             None => (),
310             e => panic!("Expecting None, found {:?}", e),
311         }
312     }
313 
314     // virtual </inner>
315     match r.read_namespaced_event(&mut buf, &mut ns_buf) {
316         Ok((Some(ns), End(e))) => {
317             assert_eq!(&ns[..], b"urn:example:i");
318             assert_eq!(e.name(), b"e");
319         }
320         e => panic!("Expected End event (</inner>), got {:?}", e),
321     }
322     // </outer>
323     match r.read_namespaced_event(&mut buf, &mut ns_buf) {
324         Ok((Some(ns), End(e))) => {
325             assert_eq!(&ns[..], b"urn:example:o");
326             assert_eq!(e.name(), b"e");
327         }
328         e => panic!("Expected End event (</outer>), got {:?}", e),
329     }
330 }
331 
332 #[test]
333 #[cfg(feature = "encoding_rs")]
test_koi8_r_encoding()334 fn test_koi8_r_encoding() {
335     let src: &[u8] = include_bytes!("documents/opennews_all.rss");
336     let mut r = Reader::from_reader(src as &[u8]);
337     r.trim_text(true).expand_empty_elements(false);
338     let mut buf = Vec::new();
339     loop {
340         match r.read_event(&mut buf) {
341             Ok(Text(e)) => {
342                 e.unescape_and_decode(&r).unwrap();
343             }
344             Ok(Eof) => break,
345             _ => (),
346         }
347     }
348 }
349 
350 #[test]
fuzz_53()351 fn fuzz_53() {
352     let data: &[u8] = b"\xe9\x00\x00\x00\x00\x00\x00\x00\x00\
353 \x00\x00\x00\x00\n(\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\
354 \x00<>\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<<\x00\x00\x00";
355     let cursor = Cursor::new(data);
356     let mut reader = Reader::from_reader(cursor);
357     let mut buf = vec![];
358     loop {
359         match reader.read_event(&mut buf) {
360             Ok(quick_xml::events::Event::Eof) | Err(..) => break,
361             _ => buf.clear(),
362         }
363     }
364 }
365 
366 #[test]
test_issue94()367 fn test_issue94() {
368     let data = br#"<Run>
369 <!B>
370 </Run>"#;
371     let mut reader = Reader::from_reader(&data[..]);
372     reader.trim_text(true);
373     let mut buf = vec![];
374     loop {
375         match reader.read_event(&mut buf) {
376             Ok(quick_xml::events::Event::Eof) | Err(..) => break,
377             _ => buf.clear(),
378         }
379         buf.clear();
380     }
381 }
382 
383 #[test]
fuzz_101()384 fn fuzz_101() {
385     let data: &[u8] = b"\x00\x00<\x00\x00\x0a>&#44444444401?#\x0a413518\
386                        #\x0a\x0a\x0a;<:<)(<:\x0a\x0a\x0a\x0a;<:\x0a\x0a\
387                        <:\x0a\x0a\x0a\x0a\x0a<\x00*\x00\x00\x00\x00";
388     let cursor = Cursor::new(data);
389     let mut reader = Reader::from_reader(cursor);
390     let mut buf = vec![];
391     loop {
392         match reader.read_event(&mut buf) {
393             Ok(Start(ref e)) | Ok(Empty(ref e)) => {
394                 if e.unescaped().is_err() {
395                     break;
396                 }
397                 for a in e.attributes() {
398                     if a.ok().map_or(true, |a| a.unescaped_value().is_err()) {
399                         break;
400                     }
401                 }
402             }
403             Ok(Text(ref e)) => {
404                 if e.unescaped().is_err() {
405                     break;
406                 }
407             }
408             Ok(Eof) | Err(..) => break,
409             _ => (),
410         }
411         buf.clear();
412     }
413 }
414 
415 #[test]
test_default_namespace()416 fn test_default_namespace() {
417     let mut r = Reader::from_str("<a ><b xmlns=\"www1\"></b></a>");
418     r.trim_text(true);
419 
420     // <a>
421     let mut buf = Vec::new();
422     let mut ns_buf = Vec::new();
423     if let Ok((None, Start(_))) = r.read_namespaced_event(&mut buf, &mut ns_buf) {
424     } else {
425         panic!("expecting outer start element with no namespace");
426     }
427 
428     // <b>
429     {
430         let event = match r.read_namespaced_event(&mut buf, &mut ns_buf) {
431             Ok((Some(b"www1"), Start(event))) => event,
432             Ok((Some(_), Start(_))) => panic!("expecting namespace to resolve to 'www1'"),
433             _ => panic!("expecting namespace resolution"),
434         };
435 
436         //We check if the resolve_namespace method also work properly
437         match r.event_namespace(event.name(), &mut ns_buf) {
438             (Some(b"www1"), _) => (),
439             (Some(_), _) => panic!("expecting namespace to resolve to 'www1'"),
440             ns => panic!(
441                 "expecting namespace resolution by the resolve_nemespace method {:?}",
442                 ns
443             ),
444         }
445     }
446 
447     // </b>
448     match r.read_namespaced_event(&mut buf, &mut ns_buf) {
449         Ok((Some(b"www1"), End(_))) => (),
450         Ok((Some(_), End(_))) => panic!("expecting namespace to resolve to 'www1'"),
451         _ => panic!("expecting namespace resolution"),
452     }
453 
454     // </a> very important: a should not be in any namespace. The default namespace only applies to
455     // the sub-document it is defined on.
456     if let Ok((None, End(_))) = r.read_namespaced_event(&mut buf, &mut ns_buf) {
457     } else {
458         panic!("expecting outer end element with no namespace");
459     }
460 }
461 
462 #[cfg(feature = "serialize")]
463 #[test]
line_score()464 fn line_score() {
465     #[derive(Debug, PartialEq, Deserialize)]
466     struct LineScoreData {
467         game_pk: u32,
468         game_type: char,
469         venue: String,
470         venue_w_chan_loc: String,
471         venue_id: u32,
472         time: String,
473         time_zone: String,
474         ampm: String,
475         home_team_id: u32,
476         home_team_city: String,
477         home_team_name: String,
478         home_league_id: u32,
479         away_team_id: u32,
480         away_team_city: String,
481         away_team_name: String,
482         away_league_id: u32,
483         #[serde(rename = "linescore", skip_serializing)]
484         innings: Vec<LineScore>,
485     }
486     #[derive(Debug, PartialEq, Deserialize)]
487     struct LineScore {
488         #[serde(rename = "away_inning_runs")]
489         away_runs: u32,
490         #[serde(rename = "home_inning_runs")]
491         //needs to be an Option, since home team doesn't always bat.
492         home_runs: Option<u32>,
493         // Keeping the inning as a string, since we'll need it to construct URLs later
494         inning: String,
495     }
496 
497     let res: LineScoreData = quick_xml::de::from_str(include_str!("linescore.xml")).unwrap();
498 
499     let expected = LineScoreData {
500         game_pk: 239575,
501         game_type: 'R',
502         venue: "Generic".to_owned(),
503         venue_w_chan_loc: "USNY0996".to_owned(),
504         venue_id: 401,
505         time: "Gm 2".to_owned(),
506         time_zone: "ET".to_owned(),
507         ampm: "AM".to_owned(),
508         home_team_id: 611,
509         home_team_city: "DSL Dodgers".to_owned(),
510         home_team_name: "DSL Dodgers".to_owned(),
511         home_league_id: 130,
512         away_team_id: 604,
513         away_team_city: "DSL Blue Jays1".to_owned(),
514         away_team_name: "DSL Blue Jays1".to_owned(),
515         away_league_id: 130,
516         innings: vec![
517             LineScore {
518                 away_runs: 1,
519                 home_runs: Some(0),
520                 inning: "1".to_owned(),
521             },
522             LineScore {
523                 away_runs: 0,
524                 home_runs: Some(0),
525                 inning: "2".to_owned(),
526             },
527             LineScore {
528                 away_runs: 1,
529                 home_runs: Some(1),
530                 inning: "3".to_owned(),
531             },
532             LineScore {
533                 away_runs: 2,
534                 home_runs: Some(0),
535                 inning: "4".to_owned(),
536             },
537             LineScore {
538                 away_runs: 0,
539                 home_runs: Some(0),
540                 inning: "5".to_owned(),
541             },
542             LineScore {
543                 away_runs: 0,
544                 home_runs: Some(0),
545                 inning: "6".to_owned(),
546             },
547             LineScore {
548                 away_runs: 0,
549                 home_runs: Some(0),
550                 inning: "7".to_owned(),
551             },
552         ],
553     };
554     assert_eq!(res, expected);
555 }
556 
557 #[cfg(feature = "serialize")]
558 #[test]
players()559 fn players() {
560     #[derive(PartialEq, Deserialize, Serialize, Debug)]
561     struct Game {
562         #[serde(rename = "team")]
563         teams: Vec<Team>,
564         //umpires: Umpires
565     }
566 
567     #[derive(PartialEq, Deserialize, Serialize, Debug)]
568     struct Team {
569         #[serde(rename = "type")]
570         home_away: HomeAway,
571         id: String,
572         name: String,
573         #[serde(rename = "player")]
574         players: Vec<Player>,
575         #[serde(rename = "coach")]
576         coaches: Vec<Coach>,
577     }
578 
579     #[derive(PartialEq, Deserialize, Serialize, Debug)]
580     enum HomeAway {
581         #[serde(rename = "home")]
582         Home,
583         #[serde(rename = "away")]
584         Away,
585     }
586 
587     #[derive(PartialEq, Deserialize, Serialize, Debug, Clone)]
588     struct Player {
589         id: u32,
590         #[serde(rename = "first")]
591         name_first: String,
592         #[serde(rename = "last")]
593         name_last: String,
594         game_position: Option<String>,
595         bat_order: Option<u8>,
596         position: String,
597     }
598 
599     #[derive(PartialEq, Deserialize, Serialize, Debug)]
600     struct Coach {
601         position: String,
602         #[serde(rename = "first")]
603         name_first: String,
604         #[serde(rename = "last")]
605         name_last: String,
606         id: u32,
607     }
608 
609     let res: Game = quick_xml::de::from_str(include_str!("players.xml")).unwrap();
610 
611     let expected = Game {
612         teams: vec![
613             Team {
614                 home_away: HomeAway::Away,
615                 id: "CIN".to_owned(),
616                 name: "Cincinnati Reds".to_owned(),
617                 players: vec![
618                     Player {
619                         id: 115135,
620                         name_first: "Ken".to_owned(),
621                         name_last: "Griffey".to_owned(),
622                         game_position: Some("RF".to_owned()),
623                         bat_order: Some(3),
624                         position: "RF".to_owned(),
625                     },
626                     Player {
627                         id: 115608,
628                         name_first: "Scott".to_owned(),
629                         name_last: "Hatteberg".to_owned(),
630                         game_position: None,
631                         bat_order: None,
632                         position: "1B".to_owned(),
633                     },
634                     Player {
635                         id: 118967,
636                         name_first: "Kent".to_owned(),
637                         name_last: "Mercker".to_owned(),
638                         game_position: None,
639                         bat_order: None,
640                         position: "P".to_owned(),
641                     },
642                     Player {
643                         id: 136460,
644                         name_first: "Alex".to_owned(),
645                         name_last: "Gonzalez".to_owned(),
646                         game_position: None,
647                         bat_order: None,
648                         position: "SS".to_owned(),
649                     },
650                     Player {
651                         id: 150020,
652                         name_first: "Jerry".to_owned(),
653                         name_last: "Hairston".to_owned(),
654                         game_position: None,
655                         bat_order: None,
656                         position: "SS".to_owned(),
657                     },
658                     Player {
659                         id: 150188,
660                         name_first: "Francisco".to_owned(),
661                         name_last: "Cordero".to_owned(),
662                         game_position: None,
663                         bat_order: None,
664                         position: "P".to_owned(),
665                     },
666                     Player {
667                         id: 150221,
668                         name_first: "Mike".to_owned(),
669                         name_last: "Lincoln".to_owned(),
670                         game_position: None,
671                         bat_order: None,
672                         position: "P".to_owned(),
673                     },
674                     Player {
675                         id: 150319,
676                         name_first: "Josh".to_owned(),
677                         name_last: "Fogg".to_owned(),
678                         game_position: None,
679                         bat_order: None,
680                         position: "P".to_owned(),
681                     },
682                     Player {
683                         id: 150472,
684                         name_first: "Ryan".to_owned(),
685                         name_last: "Freel".to_owned(),
686                         game_position: Some("LF".to_owned()),
687                         bat_order: Some(2),
688                         position: "CF".to_owned(),
689                     },
690                     Player {
691                         id: 276520,
692                         name_first: "Bronson".to_owned(),
693                         name_last: "Arroyo".to_owned(),
694                         game_position: None,
695                         bat_order: None,
696                         position: "P".to_owned(),
697                     },
698                     Player {
699                         id: 279571,
700                         name_first: "Matt".to_owned(),
701                         name_last: "Belisle".to_owned(),
702                         game_position: Some("P".to_owned()),
703                         bat_order: Some(9),
704                         position: "P".to_owned(),
705                     },
706                     Player {
707                         id: 279913,
708                         name_first: "Corey".to_owned(),
709                         name_last: "Patterson".to_owned(),
710                         game_position: Some("CF".to_owned()),
711                         bat_order: Some(1),
712                         position: "CF".to_owned(),
713                     },
714                     Player {
715                         id: 346793,
716                         name_first: "Jeremy".to_owned(),
717                         name_last: "Affeldt".to_owned(),
718                         game_position: None,
719                         bat_order: None,
720                         position: "P".to_owned(),
721                     },
722                     Player {
723                         id: 408252,
724                         name_first: "Brandon".to_owned(),
725                         name_last: "Phillips".to_owned(),
726                         game_position: Some("2B".to_owned()),
727                         bat_order: Some(4),
728                         position: "2B".to_owned(),
729                     },
730                     Player {
731                         id: 421685,
732                         name_first: "Aaron".to_owned(),
733                         name_last: "Harang".to_owned(),
734                         game_position: None,
735                         bat_order: None,
736                         position: "P".to_owned(),
737                     },
738                     Player {
739                         id: 424325,
740                         name_first: "David".to_owned(),
741                         name_last: "Ross".to_owned(),
742                         game_position: Some("C".to_owned()),
743                         bat_order: Some(8),
744                         position: "C".to_owned(),
745                     },
746                     Player {
747                         id: 429665,
748                         name_first: "Edwin".to_owned(),
749                         name_last: "Encarnacion".to_owned(),
750                         game_position: Some("3B".to_owned()),
751                         bat_order: Some(6),
752                         position: "3B".to_owned(),
753                     },
754                     Player {
755                         id: 433898,
756                         name_first: "Jeff".to_owned(),
757                         name_last: "Keppinger".to_owned(),
758                         game_position: Some("SS".to_owned()),
759                         bat_order: Some(7),
760                         position: "SS".to_owned(),
761                     },
762                     Player {
763                         id: 435538,
764                         name_first: "Bill".to_owned(),
765                         name_last: "Bray".to_owned(),
766                         game_position: None,
767                         bat_order: None,
768                         position: "P".to_owned(),
769                     },
770                     Player {
771                         id: 440361,
772                         name_first: "Norris".to_owned(),
773                         name_last: "Hopper".to_owned(),
774                         game_position: None,
775                         bat_order: None,
776                         position: "O".to_owned(),
777                     },
778                     Player {
779                         id: 450172,
780                         name_first: "Edinson".to_owned(),
781                         name_last: "Volquez".to_owned(),
782                         game_position: None,
783                         bat_order: None,
784                         position: "P".to_owned(),
785                     },
786                     Player {
787                         id: 454537,
788                         name_first: "Jared".to_owned(),
789                         name_last: "Burton".to_owned(),
790                         game_position: None,
791                         bat_order: None,
792                         position: "P".to_owned(),
793                     },
794                     Player {
795                         id: 455751,
796                         name_first: "Bobby".to_owned(),
797                         name_last: "Livingston".to_owned(),
798                         game_position: None,
799                         bat_order: None,
800                         position: "P".to_owned(),
801                     },
802                     Player {
803                         id: 456501,
804                         name_first: "Johnny".to_owned(),
805                         name_last: "Cueto".to_owned(),
806                         game_position: None,
807                         bat_order: None,
808                         position: "P".to_owned(),
809                     },
810                     Player {
811                         id: 458015,
812                         name_first: "Joey".to_owned(),
813                         name_last: "Votto".to_owned(),
814                         game_position: Some("1B".to_owned()),
815                         bat_order: Some(5),
816                         position: "1B".to_owned(),
817                     },
818                 ],
819                 coaches: vec![
820                     Coach {
821                         position: "manager".to_owned(),
822                         name_first: "Dusty".to_owned(),
823                         name_last: "Baker".to_owned(),
824                         id: 110481,
825                     },
826                     Coach {
827                         position: "batting_coach".to_owned(),
828                         name_first: "Brook".to_owned(),
829                         name_last: "Jacoby".to_owned(),
830                         id: 116461,
831                     },
832                     Coach {
833                         position: "pitching_coach".to_owned(),
834                         name_first: "Dick".to_owned(),
835                         name_last: "Pole".to_owned(),
836                         id: 120649,
837                     },
838                     Coach {
839                         position: "first_base_coach".to_owned(),
840                         name_first: "Billy".to_owned(),
841                         name_last: "Hatcher".to_owned(),
842                         id: 115602,
843                     },
844                     Coach {
845                         position: "third_base_coach".to_owned(),
846                         name_first: "Mark".to_owned(),
847                         name_last: "Berry".to_owned(),
848                         id: 427028,
849                     },
850                     Coach {
851                         position: "bench_coach".to_owned(),
852                         name_first: "Chris".to_owned(),
853                         name_last: "Speier".to_owned(),
854                         id: 122573,
855                     },
856                     Coach {
857                         position: "bullpen_coach".to_owned(),
858                         name_first: "Juan".to_owned(),
859                         name_last: "Lopez".to_owned(),
860                         id: 427306,
861                     },
862                     Coach {
863                         position: "bullpen_catcher".to_owned(),
864                         name_first: "Mike".to_owned(),
865                         name_last: "Stefanski".to_owned(),
866                         id: 150464,
867                     },
868                 ],
869             },
870             Team {
871                 home_away: HomeAway::Home,
872                 id: "NYM".to_owned(),
873                 name: "New York Mets".to_owned(),
874                 players: vec![
875                     Player {
876                         id: 110189,
877                         name_first: "Moises".to_owned(),
878                         name_last: "Alou".to_owned(),
879                         game_position: Some("LF".to_owned()),
880                         bat_order: Some(6),
881                         position: "LF".to_owned(),
882                     },
883                     Player {
884                         id: 112116,
885                         name_first: "Luis".to_owned(),
886                         name_last: "Castillo".to_owned(),
887                         game_position: Some("2B".to_owned()),
888                         bat_order: Some(2),
889                         position: "2B".to_owned(),
890                     },
891                     Player {
892                         id: 113232,
893                         name_first: "Carlos".to_owned(),
894                         name_last: "Delgado".to_owned(),
895                         game_position: Some("1B".to_owned()),
896                         bat_order: Some(7),
897                         position: "1B".to_owned(),
898                     },
899                     Player {
900                         id: 113702,
901                         name_first: "Damion".to_owned(),
902                         name_last: "Easley".to_owned(),
903                         game_position: None,
904                         bat_order: None,
905                         position: "2B".to_owned(),
906                     },
907                     Player {
908                         id: 118377,
909                         name_first: "Pedro".to_owned(),
910                         name_last: "Martinez".to_owned(),
911                         game_position: None,
912                         bat_order: None,
913                         position: "P".to_owned(),
914                     },
915                     Player {
916                         id: 123790,
917                         name_first: "Billy".to_owned(),
918                         name_last: "Wagner".to_owned(),
919                         game_position: None,
920                         bat_order: None,
921                         position: "P".to_owned(),
922                     },
923                     Player {
924                         id: 133340,
925                         name_first: "Orlando".to_owned(),
926                         name_last: "Hernandez".to_owned(),
927                         game_position: None,
928                         bat_order: None,
929                         position: "P".to_owned(),
930                     },
931                     Player {
932                         id: 135783,
933                         name_first: "Ramon".to_owned(),
934                         name_last: "Castro".to_owned(),
935                         game_position: None,
936                         bat_order: None,
937                         position: "C".to_owned(),
938                     },
939                     Player {
940                         id: 136724,
941                         name_first: "Marlon".to_owned(),
942                         name_last: "Anderson".to_owned(),
943                         game_position: None,
944                         bat_order: None,
945                         position: "LF".to_owned(),
946                     },
947                     Player {
948                         id: 136860,
949                         name_first: "Carlos".to_owned(),
950                         name_last: "Beltran".to_owned(),
951                         game_position: Some("CF".to_owned()),
952                         bat_order: Some(4),
953                         position: "CF".to_owned(),
954                     },
955                     Player {
956                         id: 150411,
957                         name_first: "Brian".to_owned(),
958                         name_last: "Schneider".to_owned(),
959                         game_position: Some("C".to_owned()),
960                         bat_order: Some(8),
961                         position: "C".to_owned(),
962                     },
963                     Player {
964                         id: 276371,
965                         name_first: "Johan".to_owned(),
966                         name_last: "Santana".to_owned(),
967                         game_position: Some("P".to_owned()),
968                         bat_order: Some(9),
969                         position: "P".to_owned(),
970                     },
971                     Player {
972                         id: 277184,
973                         name_first: "Matt".to_owned(),
974                         name_last: "Wise".to_owned(),
975                         game_position: None,
976                         bat_order: None,
977                         position: "P".to_owned(),
978                     },
979                     Player {
980                         id: 346795,
981                         name_first: "Endy".to_owned(),
982                         name_last: "Chavez".to_owned(),
983                         game_position: None,
984                         bat_order: None,
985                         position: "RF".to_owned(),
986                     },
987                     Player {
988                         id: 407901,
989                         name_first: "Jorge".to_owned(),
990                         name_last: "Sosa".to_owned(),
991                         game_position: None,
992                         bat_order: None,
993                         position: "P".to_owned(),
994                     },
995                     Player {
996                         id: 408230,
997                         name_first: "Pedro".to_owned(),
998                         name_last: "Feliciano".to_owned(),
999                         game_position: None,
1000                         bat_order: None,
1001                         position: "P".to_owned(),
1002                     },
1003                     Player {
1004                         id: 408310,
1005                         name_first: "Aaron".to_owned(),
1006                         name_last: "Heilman".to_owned(),
1007                         game_position: None,
1008                         bat_order: None,
1009                         position: "P".to_owned(),
1010                     },
1011                     Player {
1012                         id: 408314,
1013                         name_first: "Jose".to_owned(),
1014                         name_last: "Reyes".to_owned(),
1015                         game_position: Some("SS".to_owned()),
1016                         bat_order: Some(1),
1017                         position: "SS".to_owned(),
1018                     },
1019                     Player {
1020                         id: 425508,
1021                         name_first: "Ryan".to_owned(),
1022                         name_last: "Church".to_owned(),
1023                         game_position: Some("RF".to_owned()),
1024                         bat_order: Some(5),
1025                         position: "RF".to_owned(),
1026                     },
1027                     Player {
1028                         id: 429720,
1029                         name_first: "John".to_owned(),
1030                         name_last: "Maine".to_owned(),
1031                         game_position: None,
1032                         bat_order: None,
1033                         position: "P".to_owned(),
1034                     },
1035                     Player {
1036                         id: 431151,
1037                         name_first: "David".to_owned(),
1038                         name_last: "Wright".to_owned(),
1039                         game_position: Some("3B".to_owned()),
1040                         bat_order: Some(3),
1041                         position: "3B".to_owned(),
1042                     },
1043                     Player {
1044                         id: 434586,
1045                         name_first: "Ambiorix".to_owned(),
1046                         name_last: "Burgos".to_owned(),
1047                         game_position: None,
1048                         bat_order: None,
1049                         position: "P".to_owned(),
1050                     },
1051                     Player {
1052                         id: 434636,
1053                         name_first: "Angel".to_owned(),
1054                         name_last: "Pagan".to_owned(),
1055                         game_position: None,
1056                         bat_order: None,
1057                         position: "LF".to_owned(),
1058                     },
1059                     Player {
1060                         id: 450306,
1061                         name_first: "Jason".to_owned(),
1062                         name_last: "Vargas".to_owned(),
1063                         game_position: None,
1064                         bat_order: None,
1065                         position: "P".to_owned(),
1066                     },
1067                     Player {
1068                         id: 460059,
1069                         name_first: "Mike".to_owned(),
1070                         name_last: "Pelfrey".to_owned(),
1071                         game_position: None,
1072                         bat_order: None,
1073                         position: "P".to_owned(),
1074                     },
1075                 ],
1076                 coaches: vec![
1077                     Coach {
1078                         position: "manager".to_owned(),
1079                         name_first: "Willie".to_owned(),
1080                         name_last: "Randolph".to_owned(),
1081                         id: 120927,
1082                     },
1083                     Coach {
1084                         position: "batting_coach".to_owned(),
1085                         name_first: "Howard".to_owned(),
1086                         name_last: "Johnson".to_owned(),
1087                         id: 116593,
1088                     },
1089                     Coach {
1090                         position: "pitching_coach".to_owned(),
1091                         name_first: "Rick".to_owned(),
1092                         name_last: "Peterson".to_owned(),
1093                         id: 427395,
1094                     },
1095                     Coach {
1096                         position: "first_base_coach".to_owned(),
1097                         name_first: "Tom".to_owned(),
1098                         name_last: "Nieto".to_owned(),
1099                         id: 119796,
1100                     },
1101                     Coach {
1102                         position: "third_base_coach".to_owned(),
1103                         name_first: "Sandy".to_owned(),
1104                         name_last: "Alomar".to_owned(),
1105                         id: 110185,
1106                     },
1107                     Coach {
1108                         position: "bench_coach".to_owned(),
1109                         name_first: "Jerry".to_owned(),
1110                         name_last: "Manuel".to_owned(),
1111                         id: 118262,
1112                     },
1113                     Coach {
1114                         position: "bullpen_coach".to_owned(),
1115                         name_first: "Guy".to_owned(),
1116                         name_last: "Conti".to_owned(),
1117                         id: 434699,
1118                     },
1119                     Coach {
1120                         position: "bullpen_catcher".to_owned(),
1121                         name_first: "Dave".to_owned(),
1122                         name_last: "Racaniello".to_owned(),
1123                         id: 534948,
1124                     },
1125                     Coach {
1126                         position: "coach".to_owned(),
1127                         name_first: "Sandy".to_owned(),
1128                         name_last: "Alomar".to_owned(),
1129                         id: 110184,
1130                     },
1131                     Coach {
1132                         position: "coach".to_owned(),
1133                         name_first: "Juan".to_owned(),
1134                         name_last: "Lopez".to_owned(),
1135                         id: 495390,
1136                     },
1137                 ],
1138             },
1139         ],
1140     };
1141 
1142     assert_eq!(res, expected);
1143 }
1144