1use alloc::vec::Vec;
2pub use attribute::Attribute;
3use core::fmt;
4use core::fmt::{Debug, Formatter};
5pub use element::Element;
6
7pub(crate) mod attribute;
8mod element;
9
10#[derive(Clone, Debug, PartialEq)]
24pub enum Node<Ns, Tag, Leaf, Att, Val>
25where
26 Ns: PartialEq + Clone + Debug,
27 Tag: PartialEq + Debug,
28 Leaf: PartialEq + Clone + Debug,
29 Att: PartialEq + Clone + Debug,
30 Val: PartialEq + Clone + Debug,
31{
32 Element(Element<Ns, Tag, Leaf, Att, Val>),
34 NodeList(Vec<Node<Ns, Tag, Leaf, Att, Val>>),
37 Fragment(Vec<Node<Ns, Tag, Leaf, Att, Val>>),
39 Leaf(Leaf),
41}
42
43#[derive(Debug, Copy, Clone)]
44pub enum Error {
45 AddChildrenNotAllowed,
46 AttributesNotAllowed,
47}
48
49impl fmt::Display for Error {
50 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
51 match self {
52 Self::AddChildrenNotAllowed => {
53 write!(f, "Adding children on this node variant is not allowed")
54 }
55 Self::AttributesNotAllowed => {
56 write!(
57 f,
58 "Adding or setting attibutes on this node variant is not allowed"
59 )
60 }
61 }
62 }
63}
64
65impl std::error::Error for Error {}
67
68impl<Ns, Tag, Leaf, Att, Val> Node<Ns, Tag, Leaf, Att, Val>
69where
70 Ns: PartialEq + Clone + Debug,
71 Tag: PartialEq + Debug,
72 Leaf: PartialEq + Clone + Debug,
73 Att: PartialEq + Clone + Debug,
74 Val: PartialEq + Clone + Debug,
75{
76 pub fn take_element(self) -> Option<Element<Ns, Tag, Leaf, Att, Val>> {
79 match self {
80 Node::Element(element) => Some(element),
81 _ => None,
82 }
83 }
84
85 pub fn leaf(&self) -> Option<&Leaf> {
87 match self {
88 Node::Leaf(leaf) => Some(leaf),
89 _ => None,
90 }
91 }
92
93 pub fn is_element(&self) -> bool {
95 matches!(self, Node::Element(_))
96 }
97
98 pub fn is_leaf(&self) -> bool {
100 matches!(self, Node::Leaf(_))
101 }
102
103 pub fn is_fragment(&self) -> bool {
105 matches!(self, Node::Fragment(_))
106 }
107
108 pub fn element_mut(
110 &mut self,
111 ) -> Option<&mut Element<Ns, Tag, Leaf, Att, Val>> {
112 match *self {
113 Node::Element(ref mut element) => Some(element),
114 _ => None,
115 }
116 }
117
118 pub fn element_ref(&self) -> Option<&Element<Ns, Tag, Leaf, Att, Val>> {
120 match *self {
121 Node::Element(ref element) => Some(element),
122 _ => None,
123 }
124 }
125
126 pub fn with_children(
130 mut self,
131 children: impl IntoIterator<Item = Node<Ns, Tag, Leaf, Att, Val>>,
132 ) -> Self {
133 if let Some(element) = self.element_mut() {
134 element.add_children(children);
135 } else {
136 panic!("Can not add children to a text node");
137 }
138 self
139 }
140
141 pub fn add_children(
143 &mut self,
144 children: impl IntoIterator<Item = Node<Ns, Tag, Leaf, Att, Val>>,
145 ) -> Result<(), Error> {
146 if let Some(element) = self.element_mut() {
147 element.add_children(children);
148 Ok(())
149 } else {
150 Err(Error::AddChildrenNotAllowed)
151 }
152 }
153
154 pub fn with_attributes(
157 mut self,
158 attributes: impl IntoIterator<Item = Attribute<Ns, Att, Val>>,
159 ) -> Self {
160 if let Some(elm) = self.element_mut() {
161 elm.add_attributes(attributes);
162 } else {
163 panic!("Can not add attributes to a text node");
164 }
165 self
166 }
167
168 pub fn add_attributes(
170 &mut self,
171 attributes: impl IntoIterator<Item = Attribute<Ns, Att, Val>>,
172 ) -> Result<(), Error> {
173 if let Some(elm) = self.element_mut() {
174 elm.add_attributes(attributes);
175 Ok(())
176 } else {
177 Err(Error::AttributesNotAllowed)
178 }
179 }
180
181 pub fn attributes(&self) -> Option<&[Attribute<Ns, Att, Val>]> {
184 match *self {
185 Node::Element(ref element) => Some(element.attributes()),
186 _ => None,
187 }
188 }
189
190 pub fn tag(&self) -> Option<&Tag> {
193 if let Some(e) = self.element_ref() {
194 Some(&e.tag)
195 } else {
196 None
197 }
198 }
199
200 pub fn children(&self) -> &[Node<Ns, Tag, Leaf, Att, Val>] {
203 if let Some(element) = self.element_ref() {
204 element.children()
205 } else {
206 &[]
207 }
208 }
209
210 pub fn children_count(&self) -> usize {
212 self.children().len()
213 }
214
215 pub fn children_mut(
218 &mut self,
219 ) -> Option<&mut [Node<Ns, Tag, Leaf, Att, Val>]> {
220 if let Some(element) = self.element_mut() {
221 Some(element.children_mut())
222 } else {
223 None
224 }
225 }
226
227 pub fn swap_remove_child(
235 &mut self,
236 index: usize,
237 ) -> Node<Ns, Tag, Leaf, Att, Val> {
238 match self {
239 Node::Element(element) => element.swap_remove_child(index),
240 _ => panic!("text has no child"),
241 }
242 }
243
244 pub fn swap_children(&mut self, a: usize, b: usize) {
254 match self {
255 Node::Element(element) => element.swap_children(a, b),
256 _ => panic!("text has no child"),
257 }
258 }
259
260 pub fn node_count(&self) -> usize {
263 1 + self.descendant_node_count()
264 }
265
266 pub fn descendant_node_count(&self) -> usize {
268 let mut cnt = 0;
269 if let Node::Element(element) = self {
270 for child in element.children.iter() {
271 cnt += child.node_count();
272 }
273 }
274 cnt
275 }
276
277 pub fn set_attributes(
279 &mut self,
280 attributes: impl IntoIterator<Item = Attribute<Ns, Att, Val>>,
281 ) -> Result<(), Error> {
282 if let Some(elm) = self.element_mut() {
283 elm.set_attributes(attributes);
284 Ok(())
285 } else {
286 Err(Error::AttributesNotAllowed)
287 }
288 }
289
290 pub fn merge_attributes(
292 mut self,
293 attributes: impl IntoIterator<Item = Attribute<Ns, Att, Val>>,
294 ) -> Self {
295 if let Some(elm) = self.element_mut() {
296 elm.merge_attributes(attributes);
297 }
298 self
299 }
300
301 pub fn attribute_value(&self, name: &Att) -> Option<Vec<&Val>> {
303 if let Some(elm) = self.element_ref() {
304 elm.attribute_value(name)
305 } else {
306 None
307 }
308 }
309}
310
311#[inline]
324pub fn element<Ns, Tag, Leaf, Att, Val>(
325 tag: Tag,
326 attrs: impl IntoIterator<Item = Attribute<Ns, Att, Val>>,
327 children: impl IntoIterator<Item = Node<Ns, Tag, Leaf, Att, Val>>,
328) -> Node<Ns, Tag, Leaf, Att, Val>
329where
330 Ns: PartialEq + Clone + Debug,
331 Tag: PartialEq + Debug,
332 Leaf: PartialEq + Clone + Debug,
333 Att: PartialEq + Clone + Debug,
334 Val: PartialEq + Clone + Debug,
335{
336 element_ns(None, tag, attrs, children, false)
337}
338
339pub fn element_ns<Ns, Tag, Leaf, Att, Val>(
354 namespace: Option<Ns>,
355 tag: Tag,
356 attrs: impl IntoIterator<Item = Attribute<Ns, Att, Val>>,
357 children: impl IntoIterator<Item = Node<Ns, Tag, Leaf, Att, Val>>,
358 self_closing: bool,
359) -> Node<Ns, Tag, Leaf, Att, Val>
360where
361 Ns: PartialEq + Clone + Debug,
362 Tag: PartialEq + Debug,
363 Leaf: PartialEq + Clone + Debug,
364 Att: PartialEq + Clone + Debug,
365 Val: PartialEq + Clone + Debug,
366{
367 Node::Element(Element::new(namespace, tag, attrs, children, self_closing))
368}
369
370pub fn leaf<Ns, Tag, Leaf, Att, Val>(
372 leaf: Leaf,
373) -> Node<Ns, Tag, Leaf, Att, Val>
374where
375 Ns: PartialEq + Clone + Debug,
376 Tag: PartialEq + Debug,
377 Leaf: PartialEq + Clone + Debug,
378 Att: PartialEq + Clone + Debug,
379 Val: PartialEq + Clone + Debug,
380{
381 Node::Leaf(leaf)
382}
383
384pub fn node_list<Ns, Tag, Leaf, Att, Val>(
386 nodes: impl IntoIterator<Item = Node<Ns, Tag, Leaf, Att, Val>>,
387) -> Node<Ns, Tag, Leaf, Att, Val>
388where
389 Ns: PartialEq + Clone + Debug,
390 Tag: PartialEq + Debug,
391 Leaf: PartialEq + Clone + Debug,
392 Att: PartialEq + Clone + Debug,
393 Val: PartialEq + Clone + Debug,
394{
395 Node::NodeList(nodes.into_iter().collect())
396}
397
398pub fn fragment<Ns, Tag, Leaf, Att, Val>(
400 nodes: impl IntoIterator<Item = Node<Ns, Tag, Leaf, Att, Val>>,
401) -> Node<Ns, Tag, Leaf, Att, Val>
402where
403 Ns: PartialEq + Clone + Debug,
404 Tag: PartialEq + Debug,
405 Leaf: PartialEq + Clone + Debug,
406 Att: PartialEq + Clone + Debug,
407 Val: PartialEq + Clone + Debug,
408{
409 Node::Fragment(nodes.into_iter().collect())
410}