make creating rsx nodes from macros possible

This commit is contained in:
Evan Almloff committed 2023-06-29 12:52:27 -07:00
1 parent f5c60eeb4c
commit 8f67d0aafd
8 files changed
+54 -18

No files matched your search

-1
View File
@@ -48,7 +48,6 @@ impl Writer<'_> {
key, key,
attributes, attributes,
children, children,
_is_static,
brace, brace,
} = el; } = el;
+2 -2
View File
@@ -126,9 +126,9 @@ pub fn routable(input: TokenStream) -> TokenStream {
} }
#error_type #error_type
#display_impl #display_impl
#routable_impl #routable_impl
#parse_impl #parse_impl
-1
View File
@@ -71,7 +71,6 @@ pub fn rsx_node_from_html(node: &Node) -> Option<BodyNode> {
name: el_name, name: el_name,
children, children,
attributes, attributes,
_is_static: false,
key: None, key: None,
brace: Default::default(), brace: Default::default(),
})) }))
+1
View File
@@ -164,6 +164,7 @@ impl ToTokens for Component {
if !self.children.is_empty() { if !self.children.is_empty() {
let renderer: TemplateRenderer = TemplateRenderer { let renderer: TemplateRenderer = TemplateRenderer {
roots: &self.children, roots: &self.children,
location: None,
}; };
toks.append_all(quote! { toks.append_all(quote! {
-2
View File
@@ -20,7 +20,6 @@ pub struct Element {
pub key: Option<IfmtInput>, pub key: Option<IfmtInput>,
pub attributes: Vec<ElementAttrNamed>, pub attributes: Vec<ElementAttrNamed>,
pub children: Vec<BodyNode>, pub children: Vec<BodyNode>,
pub _is_static: bool,
pub brace: syn::token::Brace, pub brace: syn::token::Brace,
} }
@@ -158,7 +157,6 @@ impl Parse for Element {
attributes, attributes,
children, children,
brace, brace,
_is_static: false,
}) })
} }
} }
+7
View File
@@ -20,6 +20,13 @@ pub struct IfmtInput {
} }
impl IfmtInput { impl IfmtInput {
pub fn new_static(input: &str) -> Self {
Self {
source: None,
segments: vec![Segment::Literal(input.to_string())],
}
}
pub fn is_static(&self) -> bool { pub fn is_static(&self) -> bool {
matches!(self.segments.as_slice(), &[Segment::Literal(_)] | &[]) matches!(self.segments.as_slice(), &[Segment::Literal(_)] | &[])
} }
+40 -11
View File
@@ -59,9 +59,26 @@ impl CallBody {
template: Option<CallBody>, template: Option<CallBody>,
location: &'static str, location: &'static str,
) -> Option<Template<'static>> { ) -> Option<Template<'static>> {
let mut renderer: TemplateRenderer = TemplateRenderer { roots: &self.roots }; let mut renderer: TemplateRenderer = TemplateRenderer {
roots: &self.roots,
location: None,
};
renderer.update_template::<Ctx>(template, location) renderer.update_template::<Ctx>(template, location)
} }
/// Render the template with a manually set file location. This should be used when multiple rsx! calls are used in the same macro
pub fn render_with_location(&self, location: String) -> TokenStream2 {
let body = TemplateRenderer {
roots: &self.roots,
location: Some(location),
};
quote! {
::dioxus::core::LazyNodes::new( move | __cx: &::dioxus::core::ScopeState| -> ::dioxus::core::VNode {
#body
})
}
}
} }
impl Parse for CallBody { impl Parse for CallBody {
@@ -85,7 +102,10 @@ impl Parse for CallBody {
/// Serialize the same way, regardless of flavor /// Serialize the same way, regardless of flavor
impl ToTokens for CallBody { impl ToTokens for CallBody {
fn to_tokens(&self, out_tokens: &mut TokenStream2) { fn to_tokens(&self, out_tokens: &mut TokenStream2) {
let body = TemplateRenderer { roots: &self.roots }; let body = TemplateRenderer {
roots: &self.roots,
location: None,
};
out_tokens.append_all(quote! { out_tokens.append_all(quote! {
::dioxus::core::LazyNodes::new( move | __cx: &::dioxus::core::ScopeState| -> ::dioxus::core::VNode { ::dioxus::core::LazyNodes::new( move | __cx: &::dioxus::core::ScopeState| -> ::dioxus::core::VNode {
@@ -102,6 +122,7 @@ impl ToTokens for RenderCallBody {
fn to_tokens(&self, out_tokens: &mut TokenStream2) { fn to_tokens(&self, out_tokens: &mut TokenStream2) {
let body: TemplateRenderer = TemplateRenderer { let body: TemplateRenderer = TemplateRenderer {
roots: &self.0.roots, roots: &self.0.roots,
location: None,
}; };
out_tokens.append_all(quote! { out_tokens.append_all(quote! {
@@ -115,6 +136,7 @@ impl ToTokens for RenderCallBody {
pub struct TemplateRenderer<'a> { pub struct TemplateRenderer<'a> {
pub roots: &'a [BodyNode], pub roots: &'a [BodyNode],
pub location: Option<String>,
} }
impl<'a> TemplateRenderer<'a> { impl<'a> TemplateRenderer<'a> {
@@ -185,6 +207,21 @@ impl<'a> ToTokens for TemplateRenderer<'a> {
out out
}); });
let name = match self.location {
Some(ref loc) => quote! { #loc },
None => quote! {
concat!(
file!(),
":",
line!(),
":",
column!(),
":",
#root_col
)
},
};
// Render and release the mutable borrow on context // Render and release the mutable borrow on context
let roots = quote! { #( #root_printer ),* }; let roots = quote! { #( #root_printer ),* };
let node_printer = &context.dynamic_nodes; let node_printer = &context.dynamic_nodes;
@@ -194,15 +231,7 @@ impl<'a> ToTokens for TemplateRenderer<'a> {
out_tokens.append_all(quote! { out_tokens.append_all(quote! {
static TEMPLATE: ::dioxus::core::Template = ::dioxus::core::Template { static TEMPLATE: ::dioxus::core::Template = ::dioxus::core::Template {
name: concat!( name: #name,
file!(),
":",
line!(),
":",
column!(),
":",
#root_col
),
roots: &[ #roots ], roots: &[ #roots ],
node_paths: &[ #(#node_paths),* ], node_paths: &[ #(#node_paths),* ],
attr_paths: &[ #(#attr_paths),* ], attr_paths: &[ #(#attr_paths),* ],
+4 -1
View File
@@ -132,7 +132,10 @@ impl ToTokens for BodyNode {
pat, expr, body, .. pat, expr, body, ..
} = exp; } = exp;
let renderer: TemplateRenderer = TemplateRenderer { roots: body }; let renderer: TemplateRenderer = TemplateRenderer {
roots: body,
location: None,
};
tokens.append_all(quote! { tokens.append_all(quote! {
__cx.make_node( __cx.make_node(