summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAshelyn Rose <git@ashen.earth>2024-10-18 18:08:40 -0600
committerAshelyn Rose <git@ashen.earth>2024-10-18 18:08:40 -0600
commita35d336dc9a61fda931f4a9158205d590af87bd5 (patch)
treecde9b67c0a5d938d7caec596664bc9d0610b5d90 /src
Basic sync rendering
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs7
-rw-r--r--src/render.rs49
2 files changed, 56 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..717d715
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,7 @@
+mod render;
+
+pub use render::{Component, RenderNode};
+
+pub fn render_tree(parent_node: RenderNode) -> String {
+    parent_node.render_to_string()
+}
diff --git a/src/render.rs b/src/render.rs
new file mode 100644
index 0000000..33469e0
--- /dev/null
+++ b/src/render.rs
@@ -0,0 +1,49 @@
+use std::collections::HashMap;
+
+pub trait Component {
+    fn render(self: Box<Self>) -> Vec<RenderNode>;
+}
+
+pub enum RenderNode {
+    Component(Box<dyn Component>),
+    Element {
+        name: String,
+        attributes: HashMap<String, String>,
+        children: Vec<RenderNode>
+    },
+    TextNode {
+        content: String,
+    },
+    Portal,
+    Null,
+}
+
+impl RenderNode {
+    pub(crate) fn render_to_string(self) -> String {
+        match self {
+            RenderNode::Component(component) => {
+                let elements = component.render();
+                elements.into_iter()
+                    .map(|child| child.render_to_string())
+                    .collect::<Vec<_>>().join("")
+
+            },
+
+            RenderNode::Element { name, attributes, children } => {
+                let text_attributes = attributes.into_iter()
+                    .map(|(key, value)| format!(" {key}=\"{value}\""))
+                    .collect::<Vec<_>>().join("");
+
+                let rendered_children = children.into_iter()
+                    .map(|child| child.render_to_string())
+                    .collect::<Vec<_>>().join("");
+
+                format!("<{name}{text_attributes}>{rendered_children}</{name}>")
+            },
+
+            RenderNode::TextNode { content } => content,
+            RenderNode::Portal => todo!(),
+            RenderNode::Null => "".to_string(),
+        }
+    }
+}