lib.rs

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