summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock166
-rw-r--r--Cargo.toml8
-rw-r--r--modules/proc/Cargo.toml3
-rw-r--r--modules/proc/src/lib.rs0
-rw-r--r--modules/site_test/Cargo.toml2
-rw-r--r--modules/site_test/src/main.rs2
-rw-r--r--src/lib.rs9
-rw-r--r--src/render.rs41
8 files changed, 206 insertions, 25 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4809d49..7238fe6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,14 +1,114 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
-version = 3
+version = 4
 
 [[package]]
-name = "morgana"
-version = "0.1.0"
+name = "autocfg"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
 
 [[package]]
-name = "morgana_proc"
-version = "0.0.0"
+name = "futures"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+
+[[package]]
+name = "futures-task"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+
+[[package]]
+name = "futures-util"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "morgana"
+version = "0.1.0"
+dependencies = [
+ "futures",
+]
 
 [[package]]
 name = "morgana_site_test"
@@ -16,3 +116,59 @@ version = "0.0.0"
 dependencies = [
  "morgana",
 ]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
diff --git a/Cargo.toml b/Cargo.toml
index fa0dafb..7fea5f5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,13 @@
 [workspace]
-members = ["modules/proc", "modules/site_test"]
+members = ["modules/site_test"]
 
 [package]
 name = "morgana"
 version = "0.1.0"
 edition = "2021"
+
+[dependencies]
+futures = "0.3.31"
+
+[features]
+blocking = ["futures/executor"]
diff --git a/modules/proc/Cargo.toml b/modules/proc/Cargo.toml
deleted file mode 100644
index 16bcbb8..0000000
--- a/modules/proc/Cargo.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-[package]
-name = "morgana_proc"
-edition = "2021"
diff --git a/modules/proc/src/lib.rs b/modules/proc/src/lib.rs
deleted file mode 100644
index e69de29..0000000
--- a/modules/proc/src/lib.rs
+++ /dev/null
diff --git a/modules/site_test/Cargo.toml b/modules/site_test/Cargo.toml
index 118c9bd..e9031e5 100644
--- a/modules/site_test/Cargo.toml
+++ b/modules/site_test/Cargo.toml
@@ -3,4 +3,4 @@ name = "morgana_site_test"
 edition = "2021"
 
 [dependencies]
-morgana = { path = "../../" }
+morgana = { path = "../../", features = ["blocking"] }
diff --git a/modules/site_test/src/main.rs b/modules/site_test/src/main.rs
index 3062c11..7ef98a1 100644
--- a/modules/site_test/src/main.rs
+++ b/modules/site_test/src/main.rs
@@ -15,7 +15,7 @@ pub fn main() {
         ]
     };
 
-    let text = morgana::render_tree(RenderNode::Component(Box::new(parent)));
+    let text = morgana::render_tree_blocking(RenderNode::Component(Box::new(parent)));
     println!("{text}")
 }
 
diff --git a/src/lib.rs b/src/lib.rs
index 717d715..0178d60 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,6 +2,11 @@ mod render;
 
 pub use render::{Component, RenderNode};
 
-pub fn render_tree(parent_node: RenderNode) -> String {
-    parent_node.render_to_string()
+pub async fn render_tree(parent_node: RenderNode) -> String {
+    parent_node.render_to_string().await
+}
+
+#[cfg(feature = "blocking")]
+pub fn render_tree_blocking(parent_node: RenderNode) -> String {
+    futures::executor::block_on(render_tree(parent_node))
 }
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())()),
         }
     }
 }