From 8f67d0aafd6692b4832cfb0e87c05a4b03aa8476 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 29 Jun 2023 12:52:27 -0700 Subject: [PATCH] make creating rsx nodes from macros possible --- packages/autofmt/src/element.rs | 1 - packages/router-macro/src/lib.rs | 4 +-- packages/rsx-rosetta/src/lib.rs | 1 - packages/rsx/src/component.rs | 1 + packages/rsx/src/element.rs | 2 -- packages/rsx/src/ifmt.rs | 7 +++++ packages/rsx/src/lib.rs | 51 +++++++++++++++++++++++++------- packages/rsx/src/node.rs | 5 +++- 8 files changed, 54 insertions(+), 18 deletions(-) diff --git a/packages/autofmt/src/element.rs b/packages/autofmt/src/element.rs index 50a991897..c541c8f5c 100644 --- a/packages/autofmt/src/element.rs +++ b/packages/autofmt/src/element.rs @@ -48,7 +48,6 @@ impl Writer<'_> { key, attributes, children, - _is_static, brace, } = el; diff --git a/packages/router-macro/src/lib.rs b/packages/router-macro/src/lib.rs index df98273f7..8cbbe33c7 100644 --- a/packages/router-macro/src/lib.rs +++ b/packages/router-macro/src/lib.rs @@ -126,9 +126,9 @@ pub fn routable(input: TokenStream) -> TokenStream { } #error_type - + #display_impl - + #routable_impl #parse_impl diff --git a/packages/rsx-rosetta/src/lib.rs b/packages/rsx-rosetta/src/lib.rs index 4f30c0081..2ceb5f038 100644 --- a/packages/rsx-rosetta/src/lib.rs +++ b/packages/rsx-rosetta/src/lib.rs @@ -71,7 +71,6 @@ pub fn rsx_node_from_html(node: &Node) -> Option { name: el_name, children, attributes, - _is_static: false, key: None, brace: Default::default(), })) diff --git a/packages/rsx/src/component.rs b/packages/rsx/src/component.rs index 5dc18e0e6..c9a704ede 100644 --- a/packages/rsx/src/component.rs +++ b/packages/rsx/src/component.rs @@ -164,6 +164,7 @@ impl ToTokens for Component { if !self.children.is_empty() { let renderer: TemplateRenderer = TemplateRenderer { roots: &self.children, + location: None, }; toks.append_all(quote! { diff --git a/packages/rsx/src/element.rs b/packages/rsx/src/element.rs index 466200eca..45cfbc1c6 100644 --- a/packages/rsx/src/element.rs +++ b/packages/rsx/src/element.rs @@ -20,7 +20,6 @@ pub struct Element { pub key: Option, pub attributes: Vec, pub children: Vec, - pub _is_static: bool, pub brace: syn::token::Brace, } @@ -158,7 +157,6 @@ impl Parse for Element { attributes, children, brace, - _is_static: false, }) } } diff --git a/packages/rsx/src/ifmt.rs b/packages/rsx/src/ifmt.rs index 8146cea42..6c72f5025 100644 --- a/packages/rsx/src/ifmt.rs +++ b/packages/rsx/src/ifmt.rs @@ -20,6 +20,13 @@ pub struct 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 { matches!(self.segments.as_slice(), &[Segment::Literal(_)] | &[]) } diff --git a/packages/rsx/src/lib.rs b/packages/rsx/src/lib.rs index 07c887e65..41156e87e 100644 --- a/packages/rsx/src/lib.rs +++ b/packages/rsx/src/lib.rs @@ -59,9 +59,26 @@ impl CallBody { template: Option, location: &'static str, ) -> Option> { - let mut renderer: TemplateRenderer = TemplateRenderer { roots: &self.roots }; + let mut renderer: TemplateRenderer = TemplateRenderer { + roots: &self.roots, + location: None, + }; renderer.update_template::(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 { @@ -85,7 +102,10 @@ impl Parse for CallBody { /// Serialize the same way, regardless of flavor impl ToTokens for CallBody { 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! { ::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) { let body: TemplateRenderer = TemplateRenderer { roots: &self.0.roots, + location: None, }; out_tokens.append_all(quote! { @@ -115,6 +136,7 @@ impl ToTokens for RenderCallBody { pub struct TemplateRenderer<'a> { pub roots: &'a [BodyNode], + pub location: Option, } impl<'a> TemplateRenderer<'a> { @@ -185,6 +207,21 @@ impl<'a> ToTokens for TemplateRenderer<'a> { 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 let roots = quote! { #( #root_printer ),* }; let node_printer = &context.dynamic_nodes; @@ -194,15 +231,7 @@ impl<'a> ToTokens for TemplateRenderer<'a> { out_tokens.append_all(quote! { static TEMPLATE: ::dioxus::core::Template = ::dioxus::core::Template { - name: concat!( - file!(), - ":", - line!(), - ":", - column!(), - ":", - #root_col - ), + name: #name, roots: &[ #roots ], node_paths: &[ #(#node_paths),* ], attr_paths: &[ #(#attr_paths),* ], diff --git a/packages/rsx/src/node.rs b/packages/rsx/src/node.rs index 54448c883..91651430d 100644 --- a/packages/rsx/src/node.rs +++ b/packages/rsx/src/node.rs @@ -132,7 +132,10 @@ impl ToTokens for BodyNode { pat, expr, body, .. } = exp; - let renderer: TemplateRenderer = TemplateRenderer { roots: body }; + let renderer: TemplateRenderer = TemplateRenderer { + roots: body, + location: None, + }; tokens.append_all(quote! { __cx.make_node(