1use crate::parser::ParserError;
11use crate::{Element, EndTag, Event, StartTag, Xml};
12use std::collections::HashMap;
13use std::error::Error;
14use std::fmt;
15
16#[derive(PartialEq, Debug, Clone)]
17pub enum BuilderError {
19 Parser(ParserError),
21 ImproperNesting,
23 NoElement,
25}
26
27impl Error for BuilderError {
28 fn source(&self) -> Option<&(dyn Error + 'static)> {
29 match *self {
30 BuilderError::Parser(ref err) => Some(err),
31 _ => None,
32 }
33 }
34}
35
36impl fmt::Display for BuilderError {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 match *self {
39 BuilderError::Parser(ref err) => err.fmt(f),
40 BuilderError::ImproperNesting => write!(f, "Elements not properly nested"),
41 BuilderError::NoElement => write!(f, "No elements found"),
42 }
43 }
44}
45
46impl From<ParserError> for BuilderError {
47 fn from(err: ParserError) -> BuilderError {
48 BuilderError::Parser(err)
49 }
50}
51
52pub struct ElementBuilder {
66 stack: Vec<Element>,
67 default_ns: Vec<Option<String>>,
68 prefixes: HashMap<String, String>,
69}
70
71impl ElementBuilder {
72 pub fn new() -> ElementBuilder {
74 let mut prefixes = HashMap::with_capacity(2);
75 prefixes.insert(
76 "http://www.w3.org/XML/1998/namespace".to_owned(),
77 "xml".to_owned(),
78 );
79 prefixes.insert(
80 "http://www.w3.org/2000/xmlns/".to_owned(),
81 "xmlns".to_owned(),
82 );
83 ElementBuilder {
84 stack: Vec::new(),
85 default_ns: Vec::new(),
86 prefixes,
87 }
88 }
89
90 pub fn define_prefix(&mut self, prefix: String, ns: String) {
92 self.prefixes.insert(ns, prefix);
93 }
94
95 pub fn set_default_ns(&mut self, ns: String) {
97 self.default_ns = vec![Some(ns)];
98 }
99
100 pub fn handle_event(
106 &mut self,
107 e: Result<Event, ParserError>,
108 ) -> Option<Result<Element, BuilderError>> {
109 let e = match e {
110 Ok(o) => o,
111 Err(e) => return Some(Err(From::from(e))),
112 };
113 match e {
114 Event::PI(cont) => {
115 if let Some(elem) = self.stack.last_mut() {
116 elem.children.push(Xml::PINode(cont));
117 }
118 }
119 Event::ElementStart(StartTag {
120 name,
121 ns,
122 prefix: _,
123 attributes,
124 }) => {
125 let mut elem = Element {
126 name,
127 ns,
128 default_ns: None,
129 prefixes: self.prefixes.clone(),
130 attributes,
131 children: Vec::new(),
132 };
133
134 if let Some(default) = self.default_ns.last().cloned() {
135 self.default_ns.push(default)
136 }
137
138 for (&(ref name, ref ns), value) in &elem.attributes {
139 if ns.is_none() && name == "xmlns" {
140 self.default_ns.pop();
141 if value.is_empty() {
142 self.default_ns.push(None);
143 } else {
144 self.default_ns.push(Some(value.clone()));
145 }
146 continue;
147 }
148
149 if ns
150 .as_ref()
151 .map_or(false, |x| x == "http://www.w3.org/2000/xmlns/")
152 {
153 elem.prefixes.insert(value.clone(), name.clone());
154 }
155 }
156 elem.default_ns = self.default_ns.last().unwrap_or(&None).clone();
157
158 self.stack.push(elem);
159 }
160 Event::ElementEnd(EndTag {
161 name,
162 ns,
163 prefix: _,
164 }) => {
165 let elem = match self.stack.pop() {
166 Some(elem) => elem,
167 None => return Some(Err(BuilderError::ImproperNesting)),
168 };
169 self.default_ns.pop();
170 if elem.name != name || elem.ns != ns {
171 return Some(Err(BuilderError::ImproperNesting));
172 } else {
173 match self.stack.last_mut() {
174 Some(e) => e.children.push(Xml::ElementNode(elem)),
175 None => return Some(Ok(elem)),
176 }
177 }
178 }
179 Event::Characters(chars) => {
180 if let Some(elem) = self.stack.last_mut() {
181 elem.children.push(Xml::CharacterNode(chars));
182 }
183 }
184 Event::CDATA(chars) => {
185 if let Some(elem) = self.stack.last_mut() {
186 elem.children.push(Xml::CDATANode(chars));
187 }
188 }
189 Event::Comment(cont) => {
190 if let Some(elem) = self.stack.last_mut() {
191 elem.children.push(Xml::CommentNode(cont));
192 }
193 }
194 }
195 None
196 }
197}