From b23c8c68dcc7cc0af5077f9784aa95bfecb072a8 Mon Sep 17 00:00:00 2001 From: Leo dev Date: Sun, 1 Feb 2026 10:11:41 +0100 Subject: [PATCH] Text dependencies --- examples/hello_world.rs | 12 +++++++++++- macros/src/emit.rs | 22 +++++++++++++++------- macros/src/parse.rs | 22 +++++++++++++++++++--- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/examples/hello_world.rs b/examples/hello_world.rs index ecef5bc..19fdab5 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -8,7 +8,17 @@ pub fn main() { #[component] fn App(cx: &Arc) -> View { rsx! { - "Hello World" + Card { content: "Hello World".to_string() } + } + .view(&cx) +} + +#[component] +fn Card(cx: &Arc, content: String) -> View { + let content = content.clone(); + + rsx! { + %ref content "----\n{content}\n----" } .view(&cx) } diff --git a/macros/src/emit.rs b/macros/src/emit.rs index 91f8b4f..09a7f97 100644 --- a/macros/src/emit.rs +++ b/macros/src/emit.rs @@ -38,7 +38,7 @@ fn emit_deps(deps: &[Dep]) -> TokenStream { /// Emits a Vec of dependencies as HookDependency trait objects fn emit_deps_vec(deps: &[Dep]) -> TokenStream { - let deps = deps.iter().map(|d| { + let deps = deps.iter().filter(|d| d.is_dep).map(|d| { let ident = &d.ident; quote! { @@ -54,9 +54,12 @@ fn emit_deps_vec(deps: &[Dep]) -> TokenStream { /// Emits code for a single node within a scope fn emit_node_scope(node: &RsxNode) -> TokenStream { match node { - RsxNode::Text(_) => { + RsxNode::Text { deps, .. } => { let emit = emit_node(node); + let deps_emit = emit_deps(deps); + quote! { + #deps_emit r.static_scope(move |scope| {#emit}); } } @@ -129,11 +132,16 @@ fn emit_node_scope(node: &RsxNode) -> TokenStream { fn emit_node(node: &RsxNode) -> TokenStream { match node { - RsxNode::Text(text) => quote! { - scope.view(Arc::new(move |ctx| { - ctx.draw_text(Point { x: 0, y: 0 }, &format!(#text)) - })); - }, + RsxNode::Text { text, deps } => { + let deps_emit = emit_deps(deps); + + quote! { + scope.view(Arc::new({ + #deps_emit + move |ctx| ctx.draw_text(Point { x: 0, y: 0 }, &format!(#text)) + })); + } + } RsxNode::Component { path, diff --git a/macros/src/parse.rs b/macros/src/parse.rs index 0d474e2..2908dc2 100644 --- a/macros/src/parse.rs +++ b/macros/src/parse.rs @@ -37,7 +37,7 @@ pub struct RsxProp { /// AST node representing different RSX constructs pub enum RsxNode { /// String literal: `"text"` - Text(LitStr), + Text { text: LitStr, deps: Vec }, /// Expression node: `{expr}` Expr(Expr), /// Component instantiation: `Component { prop: value, ... }` @@ -76,6 +76,7 @@ pub enum RsxNode { pub struct Dep { pub ident: Ident, pub pat: Option, + pub is_dep: bool, } fn parse_deps(input: ParseStream) -> Result> { @@ -84,7 +85,15 @@ fn parse_deps(input: ParseStream) -> Result> { if input.peek(Token![%]) { input.parse::()?; loop { + let is_ref = if input.peek(Token![ref]) { + input.parse::()?; + true + } else { + false + }; + let ident: Ident = input.parse()?; + let pat = if input.peek(Token![as]) { input.parse::()?; // Patterns in syn 2.0 are parsed via `Pat::parse_multi` @@ -94,7 +103,11 @@ fn parse_deps(input: ParseStream) -> Result> { None }; - deps.push(Dep { ident, pat }); + deps.push(Dep { + ident, + pat, + is_dep: !is_ref, + }); if !input.peek(Token![,]) { break; @@ -161,7 +174,10 @@ impl Parse for RsxNode { // "%$dep for $pat in $expr { $rsx }" if input.peek(LitStr) { - return Ok(RsxNode::Text(input.parse()?)); + return Ok(RsxNode::Text { + text: input.parse()?, + deps, + }); } parse_component_invocation(input)