bloom_core/
element.rs

1use std::{any::Any, sync::Arc};
2
3use crate::component::{AnyComponent, ComponentDiff};
4
5/// The element type is returned from component render-functions.
6/// It can be constructed from a Node-type, e.G. HtmlNode, or a Component.
7/// ```
8/// HtmlNode::element("div").attr("id", "test123").build().into()
9/// ```
10pub enum Element<Node, Error>
11where
12    Node: From<String>,
13{
14    Component(Arc<dyn AnyComponent<Node = Node, Error = Error> + Send + Sync + 'static>),
15    Node(Node, Vec<Element<Node, Error>>),
16    Fragment(Vec<Element<Node, Error>>),
17    Provider(Arc<dyn Any + Send + Sync>, Vec<Element<Node, Error>>),
18}
19
20impl<N, E> Element<N, E>
21where
22    N: From<String>,
23{
24    pub fn fragment(children: Vec<Element<N, E>>) -> Self {
25        Self::Fragment(children)
26    }
27}
28
29impl<N, E> From<Vec<Element<N, E>>> for Element<N, E>
30where
31    N: From<String>,
32{
33    fn from(children: Vec<Element<N, E>>) -> Self {
34        Element::Fragment(children)
35    }
36}
37
38impl<N, E> From<String> for Element<N, E>
39where
40    N: From<String>,
41{
42    fn from(value: String) -> Self {
43        Element::Node(N::from(value), vec![])
44    }
45}
46
47impl<N, E> From<()> for Element<N, E>
48where
49    N: From<String>,
50{
51    fn from(_: ()) -> Self {
52        Element::Fragment(Vec::new())
53    }
54}
55
56impl<N, E> PartialEq for Element<N, E>
57where
58    N: From<String> + PartialEq + 'static,
59    E: 'static,
60{
61    fn eq(&self, other: &Self) -> bool {
62        match (self, other) {
63            (Element::Component(a), Element::Component(b)) => a.compare(b) == ComponentDiff::Equal,
64            (Element::Node(a, ac), Element::Node(b, bc)) => a == b && ac == bc,
65            (Element::Fragment(ac), Element::Fragment(bc)) => ac == bc,
66            (Element::Provider(av, ac), Element::Provider(bv, bc)) => {
67                Arc::ptr_eq(av, bv) && ac == bc
68            }
69            _ => false,
70        }
71    }
72}
73
74impl<N, E> Clone for Element<N, E>
75where
76    N: From<String> + Clone,
77{
78    fn clone(&self) -> Self {
79        match self {
80            Element::Component(component) => Element::Component(component.clone()),
81            Element::Fragment(children) => Element::Fragment(children.clone()),
82            Element::Node(node, children) => Element::Node(node.clone(), children.clone()),
83            Element::Provider(value, children) => {
84                Element::Provider(value.clone(), children.clone())
85            }
86        }
87    }
88}