node.rs

  1//! Provides the `Node` struct, which represents a node in the DOM.
  2
  3use std::io::Write;
  4
  5use quick_xml::Writer as EventWriter;
  6use quick_xml::events::{Event, BytesText};
  7
  8use error::Result;
  9
 10use element::{Element, ElementBuilder};
 11
 12/// A node in an element tree.
 13#[derive(Clone, Debug, PartialEq, Eq)]
 14pub enum Node {
 15    /// An `Element`.
 16    Element(Element),
 17    /// A text node.
 18    Text(String),
 19    /// A comment node.
 20    Comment(String),
 21}
 22
 23impl Node {
 24    /// Turns this into a reference to an `Element` if this is an element node.
 25    /// Else this returns `None`.
 26    ///
 27    /// # Examples
 28    ///
 29    /// ```rust
 30    /// use minidom::Node;
 31    ///
 32    /// let elm = Node::Element("<meow />".parse().unwrap());
 33    /// let txt = Node::Text("meow".to_owned());
 34    ///
 35    /// assert_eq!(elm.as_element().unwrap().name(), "meow");
 36    /// assert_eq!(txt.as_element(), None);
 37    /// ```
 38    pub fn as_element(&self) -> Option<&Element> {
 39        match *self {
 40            Node::Element(ref e) => Some(e),
 41            Node::Text(_) => None,
 42            Node::Comment(_) => None,
 43        }
 44    }
 45
 46    /// Turns this into a mutable reference of an `Element` if this is an element node.
 47    /// Else this returns `None`.
 48    ///
 49    /// # Examples
 50    ///
 51    /// ```rust
 52    /// use minidom::Node;
 53    ///
 54    /// let mut elm = Node::Element("<meow />".parse().unwrap());
 55    /// let mut txt = Node::Text("meow".to_owned());
 56    ///
 57    /// assert_eq!(elm.as_element_mut().unwrap().name(), "meow");
 58    /// assert_eq!(txt.as_element_mut(), None);
 59    /// ```
 60    pub fn as_element_mut(&mut self) -> Option<&mut Element> {
 61        match *self {
 62            Node::Element(ref mut e) => Some(e),
 63            Node::Text(_) => None,
 64            Node::Comment(_) => None,
 65        }
 66    }
 67
 68    /// Turns this into an `Element`, consuming self, if this is an element node.
 69    /// Else this returns `None`.
 70    ///
 71    /// # Examples
 72    ///
 73    /// ```rust
 74    /// use minidom::Node;
 75    ///
 76    /// let elm = Node::Element("<meow />".parse().unwrap());
 77    /// let txt = Node::Text("meow".to_owned());
 78    ///
 79    /// assert_eq!(elm.into_element().unwrap().name(), "meow");
 80    /// assert_eq!(txt.into_element(), None);
 81    /// ```
 82    pub fn into_element(self) -> Option<Element> {
 83        match self {
 84            Node::Element(e) => Some(e),
 85            Node::Text(_) => None,
 86            Node::Comment(_) => None,
 87        }
 88    }
 89
 90    /// Turns this into an `&str` if this is a text node.
 91    /// Else this returns `None`.
 92    ///
 93    /// # Examples
 94    ///
 95    /// ```rust
 96    /// use minidom::Node;
 97    ///
 98    /// let elm = Node::Element("<meow />".parse().unwrap());
 99    /// let txt = Node::Text("meow".to_owned());
100    ///
101    /// assert_eq!(elm.as_text(), None);
102    /// assert_eq!(txt.as_text().unwrap(), "meow");
103    /// ```
104    pub fn as_text(&self) -> Option<&str> {
105        match *self {
106            Node::Element(_) => None,
107            Node::Text(ref s) => Some(s),
108            Node::Comment(_) => None,
109        }
110    }
111
112    /// Turns this into an `&mut String` if this is a text node.
113    /// Else this returns `None`.
114    ///
115    /// # Examples
116    ///
117    /// ```rust
118    /// use minidom::Node;
119    ///
120    /// let mut elm = Node::Element("<meow />".parse().unwrap());
121    /// let mut txt = Node::Text("meow".to_owned());
122    ///
123    /// assert_eq!(elm.as_text_mut(), None);
124    /// {
125    ///     let text_mut = txt.as_text_mut().unwrap();
126    ///     assert_eq!(text_mut, "meow");
127    ///     text_mut.push_str("zies");
128    ///     assert_eq!(text_mut, "meowzies");
129    /// }
130    /// assert_eq!(txt.as_text().unwrap(), "meowzies");
131    /// ```
132    pub fn as_text_mut(&mut self) -> Option<&mut String> {
133        match *self {
134            Node::Element(_) => None,
135            Node::Text(ref mut s) => Some(s),
136            Node::Comment(_) => None,
137        }
138    }
139
140    /// Turns this into an `String`, consuming self, if this is a text node.
141    /// Else this returns `None`.
142    ///
143    /// # Examples
144    ///
145    /// ```rust
146    /// use minidom::Node;
147    ///
148    /// let elm = Node::Element("<meow />".parse().unwrap());
149    /// let txt = Node::Text("meow".to_owned());
150    ///
151    /// assert_eq!(elm.into_text(), None);
152    /// assert_eq!(txt.into_text().unwrap(), "meow");
153    /// ```
154    pub fn into_text(self) -> Option<String> {
155        match self {
156            Node::Element(_) => None,
157            Node::Text(s) => Some(s),
158            Node::Comment(_) => None,
159        }
160    }
161
162    #[doc(hidden)]
163    pub(crate) fn write_to_inner<W: Write>(&self, writer: &mut EventWriter<W>) -> Result<()>{
164        match *self {
165            Node::Element(ref elmt) => elmt.write_to_inner(writer)?,
166            Node::Text(ref s) => {
167                writer.write_event(Event::Text(BytesText::from_plain_str(s)))?;
168            },
169            Node::Comment(ref s) => {
170                writer.write_event(Event::Comment(BytesText::from_plain_str(s)))?;
171            },
172        }
173
174        Ok(())
175    }
176}
177
178impl From<Element> for Node {
179    fn from(elm: Element) -> Node {
180        Node::Element(elm)
181    }
182}
183
184impl From<String> for Node {
185    fn from(s: String) -> Node {
186        Node::Text(s)
187    }
188}
189
190impl<'a> From<&'a str> for Node {
191    fn from(s: &'a str) -> Node {
192        Node::Text(s.to_owned())
193    }
194}
195
196impl From<ElementBuilder> for Node {
197    fn from(builder: ElementBuilder) -> Node {
198        Node::Element(builder.build())
199    }
200}