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