1use {XmlElement, XmlElementBuilder};
2
3use xml::reader::{XmlEvent, EventReader};
4
5use std::io::BufReader;
6
7#[derive(Debug, PartialEq)]
8pub enum ParseError
9{
10 MalformedXml,
11}
12
13#[derive(Debug)]
14pub struct XmlParser;
15
16impl XmlParser
17{
18 pub fn parse(data : &str) -> Result<XmlElement, ParseError>
19 {
20 let reader = BufReader::new(data.as_bytes());
21 let mut builders = Vec::<XmlElementBuilder>::new();
22 for event in EventReader::new(reader).into_iter().filter_map(|e| e.ok())
23 {
24 if Self::is_start_event(&event)
25 {
26 builders.push(XmlElementBuilder::new(event));
27 }
28 else if Self::is_data_event(&event)
29 {
30 builders.last_mut().map(|b| b.add_data(event));
31
32 }
33 else if Self::is_end_event(&event)
34 {
35 let finished_element_builder = builders.pop().unwrap();
36 if builders.is_empty() {return Ok(finished_element_builder.build())}
38 else {
40 let mut parent = builders.last_mut().unwrap();
41 parent.add_child(finished_element_builder);}
42 }
43 }
44 Err(ParseError::MalformedXml)
45 }
46
47 fn is_start_event(event : &XmlEvent) -> bool
48 {
49 match event
50 {
51 &XmlEvent::StartElement{..} => true,
52 _ => false
53 }
54 }
55
56 fn is_end_event(event : &XmlEvent) -> bool
57 {
58 match event
59 {
60 &XmlEvent::EndElement{..} => true,
61 _ => false
62 }
63 }
64
65 fn is_data_event(event: &XmlEvent) -> bool
66 {
67 match event
68 {
69 &XmlEvent::Characters(_) => true,
70 _ => false
71 }
72 }
73}
74
75#[cfg(test)]
76mod xml_parser_tests
77{
78 use super::*;
79
80 #[test]
81 fn correct_number_of_elements_test() -> ()
82 {
83 let data = "<data/>";
84 let element = XmlParser::parse(data).unwrap();
85 assert_eq!(element.children().len(), 0);
86 }
87
88 #[test]
89 fn can_parse() -> ()
90 {
91 let data = "<data/>";
92 let element = XmlParser::parse(data).unwrap();
93 assert_eq!(element.name(), "data");
94 }
95
96 #[test]
97 fn can_parse_nesting() -> ()
98 {
99 let data = "<data><something/></data>";
100 let element = XmlParser::parse(data).unwrap();
101 assert_eq!(element.name(), "data");
102 assert_eq!(element.children_with_name("something").len(), 1);
103 }
104
105 #[test]
106 fn can_parse_loads_of_nesting() -> ()
107 {
108 let data = "<data><something/><something/><new_thing><something/></new_thing></data>";
109 let element = XmlParser::parse(data).unwrap();
110 assert_eq!(element.name(), "data");
111 assert_eq!(element.children_with_name("something").len(), 2);
112 let new_children = element.children_with_name("new_thing");
113 assert_eq!(new_children.len(), 1);
114 assert_eq!(new_children.first().unwrap().children_with_name("something").len(), 1);
115 }
116
117 #[test]
118 fn bad_xml_test() -> ()
119 {
120 let data = "<data>";
121 let element = XmlParser::parse(data);
122 assert_eq!(element.unwrap_err(), ParseError::MalformedXml);
123 }
124
125 #[test]
126 fn can_parse_content() -> ()
127 {
128 let data = "<data>something</data>";
129 let element = XmlParser::parse(data).unwrap();
130 assert_eq!(element.data().unwrap(), "something");
131 }
132}