1pub use simple_rsx_macros::rsx;
2use std::fmt::Display;
3
4pub enum NodeList {
5 Fragment(Vec<Node>),
6 Single(Node),
7}
8
9impl Display for NodeList {
10 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11 match self {
12 NodeList::Fragment(nodes) => {
13 for node in nodes {
14 write!(f, "{}", node)?;
15 }
16 Ok(())
17 }
18 NodeList::Single(node) => {
19 write!(f, "{}", node)?;
20 Ok(())
21 }
22 }
23 }
24}
25
26pub enum Node {
27 Element(Element),
28 Text(String),
29}
30
31impl Display for Node {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 match self {
34 Node::Element(el) => {
35 write!(f, "<{}", el.tag)?;
36 for (key, value) in &el.attributes {
37 write!(f, " {}=\"{}\"", key, value)?;
38 }
39 write!(f, ">")?;
40 for child in &el.children {
41 write!(f, "{}", child)?;
42 }
43 write!(f, "</{}>", el.tag)?;
44 Ok(())
45 }
46 Node::Text(text) => {
47 write!(f, "{}", text)?;
48 Ok(())
49 }
50 }
51 }
52}
53
54pub trait AttributeValue {
55 fn value(&self) -> String;
56}
57
58impl<T: ToString> AttributeValue for T {
59 fn value(&self) -> String {
60 self.to_string()
61 }
62}
63
64pub struct Element {
65 tag: String,
66 attributes: std::collections::HashMap<String, String>,
67 children: Vec<Node>,
68}
69
70impl Element {
71 pub fn new(tag: &str) -> Node {
72 Node::Element(Element {
73 tag: tag.to_string(),
74 attributes: std::collections::HashMap::new(),
75 children: Vec::new(),
76 })
77 }
78
79 pub fn set_attribute(&mut self, name: &str, value: impl AttributeValue) {
80 self.attributes.insert(name.to_string(), value.value());
81 }
82
83 pub fn append_child(&mut self, node: Node) {
84 self.children.push(node);
85 }
86}
87
88impl Node {
89 pub fn as_element_mut(&mut self) -> Option<&mut Element> {
90 match self {
91 Node::Element(el) => Some(el),
92 _ => None,
93 }
94 }
95
96 pub fn append_child(&mut self, node: Node) {
97 if let Node::Element(el) = self {
98 el.children.push(node);
99 }
100 }
101}
102
103pub struct TextNode;
104
105impl TextNode {
106 pub fn new(text: &str) -> Node {
107 Node::Text(text.to_string())
108 }
109}