diff --git a/modules/morgana_proc/src/lib.rs b/modules/morgana_proc/src/lib.rs
index 2f0c81b..8061b1b 100644
--- a/modules/morgana_proc/src/lib.rs
+++ b/modules/morgana_proc/src/lib.rs
@@ -25,7 +25,12 @@ pub fn morx(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = tokens.to_token_iter().parse_all::<MorxBlock>().expect("syntax error");
- generate_block(&ast).into()
+ let child_vec_expr = generate_block(&ast);
+ quote! {
+ RenderNode::Fragment {
+ children: #child_vec_expr
+ }
+ }.into()
}
fn generate_block(ast: &MorxBlock) -> unsynn::TokenStream {
@@ -46,7 +51,7 @@ fn generate_block(ast: &MorxBlock) -> unsynn::TokenStream {
}
fn generate_node(ast: &MorxNode) -> unsynn::TokenStream {
- let elem_name = ast.0.first.to_string();
+ let elem_name = &ast.0.first;
let attrs_or_props = match &ast.0.second {
Either::Fourth(cons) => {
let attrs = &cons.first;
@@ -98,19 +103,19 @@ fn generate_node(ast: &MorxNode) -> unsynn::TokenStream {
_ => quote!{ vec![] }
};
- let is_component_node = elem_name.chars().next().map_or(false, |char| char.is_uppercase());
+ let is_component_node = elem_name.to_string().chars().next().map_or(false, |char| char.is_uppercase());
if is_component_node {
quote! {
RenderNode::Component(
- Box::new(#elem_name {
+ Box::new({ #elem_name {
#(#elem_props),*
children: #children
- })
+ } })
)
}.into()
} else {
- let elem_name = Literal::string(&elem_name).into_token_stream();
+ let elem_name = Literal::string(&elem_name.to_string()).into_token_stream();
quote! {
RenderNode::Element {
name: #elem_name.to_string(),
diff --git a/modules/site_test/src/main.rs b/modules/site_test/src/main.rs
index ba40ede..9201c8a 100644
--- a/modules/site_test/src/main.rs
+++ b/modules/site_test/src/main.rs
@@ -1,21 +1,15 @@
-use std::collections::HashMap;
-
use morgana::{morx, Component, RenderNode};
pub fn main() {
- let parent = ParentLayout {
- children: vec![
- RenderNode::Component(
- Box::new(Child {
- children: vec![
- RenderNode::TextNode { content: "Hello world!".to_string() }
- ]
- })
- )
- ]
+ let parent = morx! {
+ ParentLayout {
+ Child {
+ "Hello world!"
+ }
+ }
};
- let text = morgana::render_tree_blocking(RenderNode::Component(Box::new(parent)));
+ let text = morgana::render_tree_blocking(parent);
println!("{text}")
}
@@ -24,7 +18,7 @@ struct ParentLayout {
}
impl Component for ParentLayout {
- fn render(self: Box<Self>) -> Vec<RenderNode> {
+ fn render(self: Box<Self>) -> RenderNode {
morx!{
html lang = "en-US" {
head {
@@ -41,13 +35,9 @@ struct Child {
}
impl Component for Child {
- fn render(self: Box<Self>) -> Vec<RenderNode> {
- vec![
- RenderNode::Element {
- name: "p".to_string(),
- attributes: HashMap::new(),
- children: self.children
- }
- ]
+ fn render(self: Box<Self>) -> RenderNode {
+ morx! {
+ p= {self.children}
+ }
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 2aa0d7a..c760338 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,6 @@
mod render;
-pub use render::{Component, RenderNode};
+pub use render::{RenderNode, Component};
pub use morgana_proc::morx;
pub async fn render_tree(parent_node: RenderNode) -> String {
diff --git a/src/render.rs b/src/render.rs
index 94b193b..8addbdb 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -4,7 +4,7 @@ use std::future::Future;
use futures::future::join_all;
pub trait Component {
- fn render(self: Box<Self>) -> Vec<RenderNode>;
+ fn render(self: Box<Self>) -> RenderNode;
}
pub enum RenderNode {
@@ -31,11 +31,9 @@ impl RenderNode {
pub(crate) fn render_to_string(self) -> Pin<Box<dyn Future<Output = String>>> {
match self {
RenderNode::Component(component) => {
- let elements = component.render();
+ let result_root = component.render();
Box::pin((async move || {
- join_all(elements.into_iter()
- .map(|child| child.render_to_string())
- .collect::<Vec<_>>()).await.join("")
+ result_root.render_to_string().await
})())
},
|