diff options
-rw-r--r-- | Cargo.lock | 166 | ||||
-rw-r--r-- | Cargo.toml | 8 | ||||
-rw-r--r-- | modules/proc/Cargo.toml | 3 | ||||
-rw-r--r-- | modules/proc/src/lib.rs | 0 | ||||
-rw-r--r-- | modules/site_test/Cargo.toml | 2 | ||||
-rw-r--r-- | modules/site_test/src/main.rs | 2 | ||||
-rw-r--r-- | src/lib.rs | 9 | ||||
-rw-r--r-- | src/render.rs | 41 |
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())()), } } } |