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