Rsx children scope placing

This commit is contained in:
2026-01-30 23:13:05 +01:00
parent 74e33fa4c2
commit e31c17ba41
4 changed files with 46 additions and 12 deletions
+5 -1
View File
@@ -17,5 +17,9 @@ fn App(cx: &Arc<Context>) -> View {
#[component]
fn MyComponent(cx: &Arc<Context>, children: &Rsx) -> View {
children.view(&cx)
rsx! {
"Simple"
@{children}
}
.view(&cx)
}
+8
View File
@@ -118,6 +118,10 @@ fn emit_node_scope(node: &RsxNode) -> TokenStream {
}
}
}
RsxNode::Expr(expr) => quote! {
r.child(#expr);
},
}
}
@@ -169,5 +173,9 @@ fn emit_node(node: &RsxNode) -> TokenStream {
RsxNode::If { .. } => panic!("Invalid if statement"),
RsxNode::For { .. } => panic!("Invalid for loop"),
RsxNode::Expr(expr) => quote! {
r.child(#expr);
},
}
}
+13 -7
View File
@@ -27,7 +27,7 @@ pub struct RsxProp {
pub enum RsxNode {
Text(LitStr),
/// Component with optional props and children: `Path { prop: expr, "child", ... }` or bare `Path`.
Expr(Expr),
Component {
path: Path,
props: Vec<RsxProp>,
@@ -82,6 +82,18 @@ fn parse_deps(input: ParseStream) -> Result<Vec<Dep>> {
impl Parse for RsxNode {
fn parse(input: ParseStream) -> Result<Self> {
// --- @{ expr } ---
if input.peek(Token![@]) {
input.parse::<Token![@]>()?;
let content;
braced!(content in input);
let expr: Expr = content.parse()?;
return Ok(RsxNode::Expr(expr));
}
// --- existing code ---
if input.peek(Token![!]) {
input.parse::<Token![!]>()?;
let mount: Ident = input.parse()?;
@@ -93,10 +105,8 @@ impl Parse for RsxNode {
if input.peek(Token![if]) {
input.parse::<Token![if]>()?;
let cond: Expr = input.parse()?;
let content;
braced!(content in input);
let children = parse_children(&content)?;
return Ok(RsxNode::If {
deps,
@@ -107,14 +117,11 @@ impl Parse for RsxNode {
if input.peek(Token![for]) {
input.parse::<Token![for]>()?;
// Parse a possibly multi-pattern (e.g. with `|`) for the `for` binding.
let pat: Pat = Pat::parse_multi(input)?;
input.parse::<Token![in]>()?;
let expr: Expr = input.parse()?;
let content;
braced!(content in input);
let children = parse_children(&content)?;
return Ok(RsxNode::For {
deps,
@@ -128,7 +135,6 @@ impl Parse for RsxNode {
return Ok(RsxNode::Text(input.parse()?));
}
// Component: Path or Path { props, children }
parse_component_invocation(input)
}
}
+20 -4
View File
@@ -6,15 +6,21 @@ use crate::{
View,
};
pub trait ToRsx {
fn to_rsx(&self) -> Rsx;
}
#[derive(Clone)]
pub enum RsxScope {
Static(Box<dyn Fn(&Arc<Scope>) + Send + Sync>),
Static(Arc<dyn Fn(&Arc<Scope>) + Send + Sync>),
Dynamic(
Arc<dyn Fn(&Arc<Scope>) + Send + Sync>,
Vec<Box<dyn HookDependency>>,
Vec<Arc<dyn HookDependency>>,
),
Child(Rsx),
}
#[derive(Clone)]
pub struct Rsx(Vec<RsxScope>);
impl Rsx {
@@ -23,18 +29,22 @@ impl Rsx {
}
pub fn static_scope<F: Fn(&Arc<Scope>) + Send + Sync + 'static>(&mut self, scope: F) {
self.0.push(RsxScope::Static(Box::new(scope)));
self.0.push(RsxScope::Static(Arc::new(scope)));
}
pub fn dynamic_scope<F: Fn(&Arc<Scope>) + Send + Sync + 'static>(
&mut self,
drawer: F,
dependencies: Vec<Box<dyn HookDependency>>,
dependencies: Vec<Arc<dyn HookDependency>>,
) {
self.0
.push(RsxScope::Dynamic(Arc::new(drawer), dependencies));
}
pub fn child<R: ToRsx>(&mut self, child: R) {
self.0.push(RsxScope::Child(child.to_rsx()));
}
pub fn generate_children(&self, context: &Arc<Context>) {
let executor = context.get_executor();
@@ -69,3 +79,9 @@ impl Rsx {
})
}
}
impl ToRsx for &Rsx {
fn to_rsx(&self) -> Rsx {
Rsx(self.0.clone())
}
}