simple_rsx/
lib.rs

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}