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}