From 864e058f009eb0416d86e9461726d3f97e956df9 Mon Sep 17 00:00:00 2001 From: Ashelyn Rose Date: Sat, 26 Apr 2025 21:55:30 -0600 Subject: allow doctype --- src/lib.rs | 2 +- src/render.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index c760338..5b3a634 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,6 @@ mod render; -pub use render::{RenderNode, Component}; +pub use render::{RenderNode, Component, IntoRender, DoctypeElem}; 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 8addbdb..6ae948b 100644 --- a/src/render.rs +++ b/src/render.rs @@ -7,7 +7,13 @@ pub trait Component { fn render(self: Box) -> RenderNode; } +pub enum DoctypeElem { + Word(&'static str), + String(&'static str), +} + pub enum RenderNode { + Doctype(Vec), Suspense { fallback: Box, children: Pin>>> @@ -30,19 +36,29 @@ pub enum RenderNode { impl RenderNode { pub(crate) fn render_to_string(self) -> Pin>> { match self { + RenderNode::Doctype(elements) => { + let strings = elements.iter().map(|elem| match elem { + DoctypeElem::Word(word) => word.to_string(), + DoctypeElem::String(string) => format!("\"{}\"", string), + }).collect::>().join(" ").clone(); + + Box::pin(async move { + format!("", strings) + }) + }, RenderNode::Component(component) => { let result_root = component.render(); - Box::pin((async move || { + Box::pin(async move { result_root.render_to_string().await - })()) + }) }, RenderNode::Suspense {fallback: _, children} => { - Box::pin((async move || { + Box::pin(async move { join_all(children.await.into_iter() .map(|child| child.render_to_string())).await .join("") - })()) + }) }, RenderNode::Element { name, attributes, children } => { @@ -50,25 +66,49 @@ impl RenderNode { .map(|(key, value)| format!(" {key}=\"{value}\"")) .collect::>().join(""); - Box::pin((async move || { + Box::pin(async move { let rendered_children = join_all(children.into_iter() .map(|child| child.render_to_string()) .collect::>()).await.join(""); format!("<{name}{text_attributes}>{rendered_children}") - })()) + }) }, RenderNode::Fragment { children } => { - Box::pin((async move || { + Box::pin(async move { join_all(children.into_iter() .map(|child| child.render_to_string())).await .join("") - })()) + }) } - RenderNode::TextNode { content } => Box::pin((async move || content)()), - RenderNode::Null => Box::pin((async move || "".to_string())()), + RenderNode::TextNode { content } => Box::pin(async move { content }), + RenderNode::Null => Box::pin(async move { "".to_string() }), + } + } +} + +pub trait IntoRender { + fn into_render(self) -> Vec; +} + +macro_rules! impl_str { + ($t:ty) => { + impl IntoRender for $t { + fn into_render(self) -> Vec { + vec![RenderNode::TextNode { content: String::from(self) }] + } } + }; +} + +impl_str!(String); +impl_str!(&str); +impl_str!(std::borrow::Cow<'_,str>); + +impl IntoRender for Vec { + fn into_render(self) -> Vec { + self } } -- cgit 1.4.1