1extern crate xml;
2
3pub mod error;
4pub mod attribute;
5
6use std::io::prelude::*;
7
8use std::convert::{From, AsRef};
9
10use std::iter::Iterator;
11
12use std::slice;
13
14use std::fmt;
15
16use xml::reader::{XmlEvent as ReaderEvent, EventReader};
17use xml::writer::{XmlEvent as WriterEvent, EventWriter};
18use xml::name::Name;
19use xml::namespace::NS_NO_PREFIX;
20
21use error::Error;
22
23use attribute::Attribute;
24
25#[derive(Clone, PartialEq, Eq)]
26pub struct Element {
27 name: String,
28 namespace: Option<String>,
29 attributes: Vec<Attribute>,
30 children: Vec<Fork>,
31}
32
33impl fmt::Debug for Element {
34 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
35 if let Some(ref ns) = self.namespace {
36 write!(fmt, "<{{{}}}{}", ns, self.name)?;
37 }
38 else {
39 write!(fmt, "<{}", self.name)?;
40 }
41 for attr in &self.attributes {
42 write!(fmt, " {}", attr)?;
43 }
44 write!(fmt, ">")?;
45 for child in &self.children {
46 match *child {
47 Fork::Element(ref e) => {
48 write!(fmt, "{:?}", e)?;
49 },
50 Fork::Text(ref s) => {
51 write!(fmt, "{}", s)?;
52 },
53 }
54 }
55 write!(fmt, "</{}>", self.name)?;
56 Ok(())
57 }
58}
59
60#[derive(Clone, Debug, PartialEq, Eq)]
61pub enum Fork {
62 Element(Element),
63 Text(String),
64}
65
66impl Element {
67 pub fn new(name: String, namespace: Option<String>, attributes: Vec<Attribute>) -> Element {
68 Element {
69 name: name,
70 namespace: namespace,
71 attributes: attributes,
72 children: Vec::new(),
73 }
74 }
75
76 pub fn builder<S: Into<String>>(name: S) -> ElementBuilder {
77 ElementBuilder {
78 name: name.into(),
79 namespace: None,
80 attributes: Vec::new(),
81 }
82 }
83
84 pub fn name(&self) -> &str {
85 &self.name
86 }
87
88 pub fn ns(&self) -> Option<&str> {
89 self.namespace.as_ref()
90 .map(String::as_ref)
91 }
92
93 pub fn attr(&self, name: &str) -> Option<&str> {
94 for attr in &self.attributes {
95 if attr.name == name {
96 return Some(&attr.value);
97 }
98 }
99 None
100 }
101
102 pub fn is<N: AsRef<str>, NS: AsRef<str>>(&self, name: N, namespace: NS) -> bool {
103 let ns = self.namespace.as_ref().map(String::as_ref);
104 self.name == name.as_ref() && ns == Some(namespace.as_ref())
105 }
106
107 pub fn from_reader<R: Read>(reader: &mut EventReader<R>) -> Result<Element, Error> {
108 loop {
109 let e = reader.next()?;
110 match e {
111 ReaderEvent::StartElement { name, attributes, namespace } => {
112 let attributes = attributes.into_iter()
113 .map(|o| Attribute::new(o.name.local_name, o.value))
114 .collect();
115 let ns = if let Some(ref prefix) = name.prefix {
116 namespace.get(prefix)
117 }
118 else {
119 namespace.get(NS_NO_PREFIX)
120 }.map(|s| s.to_owned());
121 let mut root = Element::new(name.local_name, ns, attributes);
122 root.from_reader_inner(reader);
123 return Ok(root);
124 },
125 ReaderEvent::EndDocument => {
126 return Err(Error::EndOfDocument);
127 },
128 _ => () // TODO: may need more errors
129 }
130 }
131 }
132
133 fn from_reader_inner<R: Read>(&mut self, reader: &mut EventReader<R>) -> Result<(), Error> {
134 loop {
135 let e = reader.next()?;
136 match e {
137 ReaderEvent::StartElement { name, attributes, namespace } => {
138 let attributes = attributes.into_iter()
139 .map(|o| Attribute::new(o.name.local_name, o.value))
140 .collect();
141 let ns = if let Some(ref prefix) = name.prefix {
142 namespace.get(prefix)
143 }
144 else {
145 namespace.get(NS_NO_PREFIX)
146 }.map(|s| s.to_owned());
147 let elem = Element::new(name.local_name, ns, attributes);
148 let elem_ref = self.append_child(elem);
149 elem_ref.from_reader_inner(reader);
150 },
151 ReaderEvent::EndElement { .. } => {
152 // TODO: may want to check whether we're closing the correct element
153 return Ok(());
154 },
155 ReaderEvent::Characters(s) => {
156 self.append_text_node(s);
157 },
158 ReaderEvent::CData(s) => {
159 self.append_text_node(s);
160 },
161 ReaderEvent::EndDocument => {
162 return Err(Error::EndOfDocument);
163 },
164 _ => (), // TODO: may need to implement more
165 }
166 }
167 }
168
169 pub fn write_to<W: Write>(&self, writer: &mut EventWriter<W>) -> Result<(), Error> {
170 let name = if let Some(ref ns) = self.namespace {
171 Name::qualified(&self.name, &ns, None)
172 }
173 else {
174 Name::local(&self.name)
175 };
176 let mut start = WriterEvent::start_element(name);
177 if let Some(ref ns) = self.namespace {
178 start = start.default_ns(ns.as_ref());
179 }
180 for attr in &self.attributes { // TODO: I think this could be done a lot more efficiently
181 start = start.attr(Name::local(&attr.name), &attr.value);
182 }
183 writer.write(start)?;
184 for child in &self.children {
185 match *child {
186 Fork::Element(ref e) => {
187 e.write_to(writer)?;
188 },
189 Fork::Text(ref s) => {
190 writer.write(WriterEvent::characters(s))?;
191 },
192 }
193 }
194 writer.write(WriterEvent::end_element())?;
195 Ok(())
196 }
197
198 pub fn children<'a>(&'a self) -> Children<'a> {
199 Children {
200 iter: self.children.iter(),
201 }
202 }
203
204 pub fn children_mut<'a>(&'a mut self) -> ChildrenMut<'a> {
205 ChildrenMut {
206 iter: self.children.iter_mut(),
207 }
208 }
209
210 pub fn append_child(&mut self, mut child: Element) -> &mut Element {
211 if child.namespace.is_none() {
212 child.namespace = self.namespace.clone();
213 }
214 self.children.push(Fork::Element(child));
215 if let Fork::Element(ref mut cld) = *self.children.last_mut().unwrap() {
216 cld
217 }
218 else {
219 unreachable!()
220 }
221 }
222
223 pub fn append_text_node<S: Into<String>>(&mut self, child: S) {
224 self.children.push(Fork::Text(child.into()));
225 }
226
227 pub fn text(&self) -> &str {
228 unimplemented!()
229 }
230
231 pub fn get_child<'a, N: Into<Name<'a>>>(&self, name: N) -> Option<&Element> {
232 unimplemented!()
233 }
234
235 pub fn get_child_mut<'a, N: Into<Name<'a>>>(&mut self, name: N) -> Option<&mut Element> {
236 unimplemented!()
237 }
238
239 pub fn into_child<'a, N: Into<Name<'a>>>(self, name: N) -> Option<Element> {
240 unimplemented!()
241 }
242}
243
244pub struct Children<'a> {
245 iter: slice::Iter<'a, Fork>,
246}
247
248impl<'a> Iterator for Children<'a> {
249 type Item = &'a Element;
250
251 fn next(&mut self) -> Option<&'a Element> {
252 while let Some(item) = self.iter.next() {
253 if let Fork::Element(ref child) = *item {
254 return Some(child);
255 }
256 }
257 None
258 }
259}
260
261pub struct ChildrenMut<'a> {
262 iter: slice::IterMut<'a, Fork>,
263}
264
265impl<'a> Iterator for ChildrenMut<'a> {
266 type Item = &'a mut Element;
267
268 fn next(&mut self) -> Option<&'a mut Element> {
269 while let Some(item) = self.iter.next() {
270 if let Fork::Element(ref mut child) = *item {
271 return Some(child);
272 }
273 }
274 None
275 }
276}
277
278pub struct ElementBuilder {
279 name: String,
280 namespace: Option<String>,
281 attributes: Vec<Attribute>,
282}
283
284impl ElementBuilder {
285 pub fn ns<S: Into<String>>(mut self, namespace: S) -> ElementBuilder {
286 self.namespace = Some(namespace.into());
287 self
288 }
289
290 pub fn attr<S: Into<String>, V: Into<String>>(mut self, name: S, value: V) -> ElementBuilder {
291 self.attributes.push(Attribute::new(name, value));
292 self
293 }
294
295 pub fn build(self) -> Element {
296 Element::new(self.name, self.namespace, self.attributes)
297 }
298}
299
300#[cfg(test)]
301mod tests {
302 use super::*;
303
304 use xml::reader::EventReader;
305 use xml::writer::EventWriter;
306
307 const TEST_STRING: &'static str = r#"<?xml version="1.0" encoding="utf-8"?><root xmlns="root_ns" a="b">meow<child c="d" /><child xmlns="child_ns" d="e" />nya</root>"#;
308
309 fn build_test_tree() -> Element {
310 let mut root = Element::builder("root")
311 .ns("root_ns")
312 .attr("a", "b")
313 .build();
314 root.append_text_node("meow");
315 let child = Element::builder("child")
316 .attr("c", "d")
317 .build();
318 root.append_child(child);
319 let other_child = Element::builder("child")
320 .ns("child_ns")
321 .attr("d", "e")
322 .build();
323 root.append_child(other_child);
324 root.append_text_node("nya");
325 root
326 }
327
328 #[test]
329 fn reader_works() {
330 use std::io::Cursor;
331 let mut reader = EventReader::new(Cursor::new(TEST_STRING));
332 assert_eq!(Element::from_reader(&mut reader).unwrap(), build_test_tree());
333 }
334
335 #[test]
336 fn writer_works() {
337 let root = build_test_tree();
338 let mut out = Vec::new();
339 {
340 let mut writer = EventWriter::new(&mut out);
341 root.write_to(&mut writer).unwrap();
342 }
343 assert_eq!(String::from_utf8(out).unwrap(), TEST_STRING);
344 }
345
346 #[test]
347 fn builder_works() {
348 let elem = Element::builder("a")
349 .ns("b")
350 .attr("c", "d")
351 .build();
352 assert_eq!(elem.name(), "a");
353 assert_eq!(elem.ns(), Some("b"));
354 assert_eq!(elem.attr("c"), Some("d"));
355 assert_eq!(elem.is("a", "b"), true);
356 }
357
358 #[test]
359 fn children_iter_works() {
360 let root = build_test_tree();
361 let mut iter = root.children();
362 assert!(iter.next().unwrap().is("child", "root_ns"));
363 assert!(iter.next().unwrap().is("child", "child_ns"));
364 assert_eq!(iter.next(), None);
365 }
366}