summary refs log tree commit diff
path: root/src/render.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/render.rs')
-rw-r--r--src/render.rs41
1 files changed, 29 insertions, 12 deletions
diff --git a/src/render.rs b/src/render.rs
index 33469e0..3bb6e41 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -1,10 +1,17 @@
+use std::pin::Pin;
 use std::collections::HashMap;
+use std::future::Future;
+use futures::future::join_all;
 
 pub trait Component {
     fn render(self: Box<Self>) -> Vec<RenderNode>;
 }
 
 pub enum RenderNode {
+    Suspense {
+        fallback: Box<RenderNode>,
+        children: Pin<Box<dyn Future<Output = Vec<RenderNode>>>>
+    },
     Component(Box<dyn Component>),
     Element {
         name: String,
@@ -14,19 +21,27 @@ pub enum RenderNode {
     TextNode {
         content: String,
     },
-    Portal,
     Null,
 }
 
 impl RenderNode {
-    pub(crate) fn render_to_string(self) -> String {
+    pub(crate) fn render_to_string(self) -> Pin<Box<dyn Future<Output = String>>> {
         match self {
             RenderNode::Component(component) => {
                 let elements = component.render();
-                elements.into_iter()
-                    .map(|child| child.render_to_string())
-                    .collect::<Vec<_>>().join("")
+                Box::pin((async move || {
+                    join_all(elements.into_iter()
+                        .map(|child| child.render_to_string())
+                        .collect::<Vec<_>>()).await.join("")
+                })())
+            },
 
+            RenderNode::Suspense {fallback: _, children} => {
+                Box::pin((async move || {
+                    join_all(children.await.into_iter()
+                        .map(|child| child.render_to_string())).await
+                        .join("")
+                })())
             },
 
             RenderNode::Element { name, attributes, children } => {
@@ -34,16 +49,18 @@ impl RenderNode {
                     .map(|(key, value)| format!(" {key}=\"{value}\""))
                     .collect::<Vec<_>>().join("");
 
-                let rendered_children = children.into_iter()
-                    .map(|child| child.render_to_string())
-                    .collect::<Vec<_>>().join("");
+                Box::pin((async move || {
+                    let rendered_children = join_all(children.into_iter()
+                        .map(|child| child.render_to_string())
+                        .collect::<Vec<_>>()).await.join("");
+
+                    format!("<{name}{text_attributes}>{rendered_children}</{name}>")
 
-                format!("<{name}{text_attributes}>{rendered_children}</{name}>")
+                })())
             },
 
-            RenderNode::TextNode { content } => content,
-            RenderNode::Portal => todo!(),
-            RenderNode::Null => "".to_string(),
+            RenderNode::TextNode { content } => Box::pin((async move || content)()),
+            RenderNode::Null => Box::pin((async move || "".to_string())()),
         }
     }
 }