1use super::{AttributeName, Namespace, Tag};
2use crate::dom::SkipDiff;
3use crate::vdom::Attribute;
4use crate::vdom::AttributeValue;
5use crate::vdom::Element;
6use crate::vdom::Leaf;
7use crate::vdom::Value;
8use derive_where::derive_where;
9use std::fmt;
10use std::fmt::{Debug, Formatter};
11
12#[derive_where(Clone, Debug, PartialEq, Eq)]
26pub enum Node<MSG> {
27 Element(Element<MSG>),
29 Leaf(Leaf<MSG>),
31}
32
33#[derive(Debug, Copy, Clone)]
34pub enum Error {
35 AddChildrenNotAllowed,
36 AttributesNotAllowed,
37}
38
39impl fmt::Display for Error {
40 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
41 match self {
42 Self::AddChildrenNotAllowed => {
43 write!(f, "Adding children on this node variant is not allowed")
44 }
45 Self::AttributesNotAllowed => {
46 write!(
47 f,
48 "Adding or setting attibutes on this node variant is not allowed"
49 )
50 }
51 }
52 }
53}
54
55impl std::error::Error for Error {}
57
58impl<MSG> Node<MSG> {
59 pub fn take_element(self) -> Option<Element<MSG>> {
62 match self {
63 Node::Element(element) => Some(element),
64 _ => None,
65 }
66 }
67
68 pub fn leaf(&self) -> Option<&Leaf<MSG>> {
70 match self {
71 Node::Leaf(leaf) => Some(leaf),
72 _ => None,
73 }
74 }
75
76 pub fn is_element(&self) -> bool {
78 matches!(self, Node::Element(_))
79 }
80
81 pub fn is_leaf(&self) -> bool {
83 matches!(self, Node::Leaf(_))
84 }
85
86 pub fn is_text(&self) -> bool {
88 match self {
89 Self::Leaf(leaf) => leaf.is_text(),
90 _ => false,
91 }
92 }
93
94 pub fn as_text(&self) -> Option<&str> {
96 match self {
97 Self::Leaf(ref leaf) => leaf.as_text(),
98 _ => None,
99 }
100 }
101
102 pub fn as_symbol(&self) -> Option<&str> {
104 match self {
105 Self::Leaf(Leaf::Symbol(symbol)) => Some(symbol),
106 _ => None,
107 }
108 }
109
110 pub fn element_mut(&mut self) -> Option<&mut Element<MSG>> {
112 match *self {
113 Node::Element(ref mut element) => Some(element),
114 _ => None,
115 }
116 }
117
118 pub fn element_ref(&self) -> Option<&Element<MSG>> {
120 match *self {
121 Node::Element(ref element) => Some(element),
122 _ => None,
123 }
124 }
125
126 pub fn with_children(mut self, children: impl IntoIterator<Item = Node<MSG>>) -> Self {
130 if let Some(element) = self.element_mut() {
131 element.add_children(children);
132 } else {
133 panic!("Can not add children to a text node");
134 }
135 self
136 }
137
138 pub fn add_children(
140 &mut self,
141 children: impl IntoIterator<Item = Node<MSG>>,
142 ) -> Result<(), Error> {
143 if let Some(element) = self.element_mut() {
144 element.add_children(children);
145 Ok(())
146 } else {
147 Err(Error::AddChildrenNotAllowed)
148 }
149 }
150
151 pub fn with_attributes(mut self, attributes: impl IntoIterator<Item = Attribute<MSG>>) -> Self {
154 if let Some(elm) = self.element_mut() {
155 elm.add_attributes(attributes);
156 } else {
157 panic!("Can not add attributes to a text node");
158 }
159 self
160 }
161
162 pub fn add_attributes(
164 &mut self,
165 attributes: impl IntoIterator<Item = Attribute<MSG>>,
166 ) -> Result<(), Error> {
167 if let Some(elm) = self.element_mut() {
168 elm.add_attributes(attributes);
169 Ok(())
170 } else {
171 Err(Error::AttributesNotAllowed)
172 }
173 }
174
175 pub fn attributes(&self) -> Option<&[Attribute<MSG>]> {
178 match self {
179 Node::Element(element) => Some(element.attributes()),
180 Node::Leaf(leaf) => leaf.attributes(),
181 }
182 }
183
184 pub fn tag(&self) -> Option<&Tag> {
187 if let Some(e) = self.element_ref() {
188 Some(&e.tag)
189 } else {
190 None
191 }
192 }
193
194 pub fn children(&self) -> &[Node<MSG>] {
197 match self {
198 Self::Element(elm) => elm.children(),
199 Self::Leaf(Leaf::StatefulComponent(comp)) => &comp.children,
200 _ => &[],
201 }
202 }
203
204 pub fn children_count(&self) -> usize {
206 self.children().len()
207 }
208
209 pub fn children_mut(&mut self) -> Option<&mut [Node<MSG>]> {
212 if let Some(element) = self.element_mut() {
213 Some(element.children_mut())
214 } else {
215 None
216 }
217 }
218
219 pub fn swap_remove_child(&mut self, index: usize) -> Node<MSG> {
227 match self {
228 Node::Element(element) => element.swap_remove_child(index),
229 _ => panic!("text has no child"),
230 }
231 }
232
233 pub fn swap_children(&mut self, a: usize, b: usize) {
243 match self {
244 Node::Element(element) => element.swap_children(a, b),
245 _ => panic!("text has no child"),
246 }
247 }
248
249 pub fn node_count(&self) -> usize {
252 1 + self.descendant_node_count()
253 }
254
255 pub fn descendant_node_count(&self) -> usize {
257 let mut cnt = 0;
258 if let Node::Element(element) = self {
259 for child in element.children().iter() {
260 cnt += child.node_count();
261 }
262 }
263 cnt
264 }
265
266 pub fn set_attributes(
268 &mut self,
269 attributes: impl IntoIterator<Item = Attribute<MSG>>,
270 ) -> Result<(), Error> {
271 if let Some(elm) = self.element_mut() {
272 elm.set_attributes(attributes);
273 Ok(())
274 } else {
275 Err(Error::AttributesNotAllowed)
276 }
277 }
278
279 pub fn merge_attributes(
281 mut self,
282 attributes: impl IntoIterator<Item = Attribute<MSG>>,
283 ) -> Self {
284 if let Some(elm) = self.element_mut() {
285 elm.merge_attributes(attributes);
286 }
287 self
288 }
289
290 pub fn attribute_value(&self, name: &AttributeName) -> Option<Vec<&AttributeValue<MSG>>> {
292 match self {
293 Self::Element(elm) => elm.attribute_value(name),
294 Self::Leaf(leaf) => leaf.attribute_value(name),
295 }
296 }
297
298 pub fn first_value(&self, att_name: &AttributeName) -> Option<&Value> {
300 self.attribute_value(att_name)
301 .and_then(|att_values| att_values.first().and_then(|v| v.get_simple()))
302 }
303
304 pub fn skip_diff(&self) -> Option<SkipDiff> {
306 match self {
307 Self::Leaf(Leaf::TemplatedView(view)) => Some((view.skip_diff)()),
308 _ => None,
309 }
310 }
311
312 pub fn unwrap_template(self) -> Node<MSG> {
314 match self {
315 Self::Leaf(Leaf::TemplatedView(view)) => *view.view,
316 _ => self,
317 }
318 }
319
320 pub fn unwrap_template_ref(&self) -> &Node<MSG> {
322 match self {
323 Self::Leaf(Leaf::TemplatedView(view)) => &view.view,
324 _ => self,
325 }
326 }
327 pub fn is_template(&self) -> bool {
329 matches!(self, Self::Leaf(Leaf::TemplatedView(_)))
330 }
331}
332
333#[inline]
345pub fn element<MSG>(
346 tag: Tag,
347 attrs: impl IntoIterator<Item = Attribute<MSG>>,
348 children: impl IntoIterator<Item = Node<MSG>>,
349) -> Node<MSG> {
350 element_ns(None, tag, attrs, children, false)
351}
352
353pub fn element_ns<MSG>(
367 namespace: Option<Namespace>,
368 tag: Tag,
369 attrs: impl IntoIterator<Item = Attribute<MSG>>,
370 children: impl IntoIterator<Item = Node<MSG>>,
371 self_closing: bool,
372) -> Node<MSG> {
373 Node::Element(Element::new(namespace, tag, attrs, children, self_closing))
374}
375
376pub fn leaf<MSG>(leaf: impl Into<Leaf<MSG>>) -> Node<MSG> {
378 Node::Leaf(leaf.into())
379}
380
381pub fn node_list<MSG>(nodes: impl IntoIterator<Item = Node<MSG>>) -> Node<MSG> {
383 Node::Leaf(Leaf::NodeList(nodes.into_iter().collect()))
384}
385
386pub fn fragment<MSG>(nodes: impl IntoIterator<Item = Node<MSG>>) -> Node<MSG> {
388 Node::Leaf(Leaf::Fragment(nodes.into_iter().collect()))
389}