feat: enable arbitrary body in rsx! macro
This commit is contained in:
1 parent
fd7933561f
commit
7aec40d57e
38 files changed
+142
-88
No files matched your search
@@ -45,27 +45,17 @@ impl Parse for Component {
|
||||
let mut children: Vec<Node> = Vec::new();
|
||||
let mut manual_props = None;
|
||||
|
||||
'parsing: loop {
|
||||
// [1] Break if empty
|
||||
if content.is_empty() {
|
||||
break 'parsing;
|
||||
}
|
||||
|
||||
if content.peek(Token![..]) {
|
||||
content.parse::<Token![..]>()?;
|
||||
manual_props = Some(content.parse::<Expr>()?);
|
||||
} else if content.peek(Ident) && content.peek2(Token![:]) {
|
||||
body.push(content.parse::<ComponentField>()?);
|
||||
} else {
|
||||
children.push(content.parse::<Node>()?);
|
||||
}
|
||||
|
||||
// consume comma if it exists
|
||||
// we don't actually care if there *are* commas between attrs
|
||||
if content.peek(Token![,]) {
|
||||
let _ = content.parse::<Token![,]>();
|
||||
}
|
||||
}
|
||||
parse_component_body(
|
||||
&content,
|
||||
&BodyParseConfig {
|
||||
allow_children: true,
|
||||
allow_fields: true,
|
||||
allow_manual_props: true,
|
||||
},
|
||||
&mut body,
|
||||
&mut children,
|
||||
&mut manual_props,
|
||||
)?;
|
||||
|
||||
Ok(Self {
|
||||
name,
|
||||
@@ -76,6 +66,52 @@ impl Parse for Component {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BodyParseConfig {
|
||||
pub allow_fields: bool,
|
||||
pub allow_children: bool,
|
||||
pub allow_manual_props: bool,
|
||||
}
|
||||
|
||||
pub fn parse_component_body(
|
||||
content: &ParseBuffer,
|
||||
cfg: &BodyParseConfig,
|
||||
body: &mut Vec<ComponentField>,
|
||||
children: &mut Vec<Node>,
|
||||
manual_props: &mut Option<Expr>,
|
||||
) -> Result<()> {
|
||||
'parsing: loop {
|
||||
// [1] Break if empty
|
||||
if content.is_empty() {
|
||||
break 'parsing;
|
||||
}
|
||||
|
||||
if content.peek(Token![..]) {
|
||||
if !cfg.allow_manual_props {
|
||||
// toss an error
|
||||
}
|
||||
content.parse::<Token![..]>()?;
|
||||
*manual_props = Some(content.parse::<Expr>()?);
|
||||
} else if content.peek(Ident) && content.peek2(Token![:]) {
|
||||
if !cfg.allow_fields {
|
||||
// toss an error
|
||||
}
|
||||
body.push(content.parse::<ComponentField>()?);
|
||||
} else {
|
||||
if !cfg.allow_children {
|
||||
// toss an error
|
||||
}
|
||||
children.push(content.parse::<Node>()?);
|
||||
}
|
||||
|
||||
// consume comma if it exists
|
||||
// we don't actually care if there *are* commas between attrs
|
||||
if content.peek(Token![,]) {
|
||||
let _ = content.parse::<Token![,]>();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl ToTokens for Component {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream2) {
|
||||
let name = &self.name;
|
||||
@@ -135,12 +171,6 @@ impl ToTokens for Component {
|
||||
let children = quote! {
|
||||
[ #( #childs ),* ]
|
||||
};
|
||||
// ChildrenList::new(__cx)
|
||||
// #( .add_child(#childs) )*
|
||||
// .finish()
|
||||
// ChildrenList::new(__cx)
|
||||
// #( .add_child(#childs) )*
|
||||
// .finish()
|
||||
|
||||
tokens.append_all(quote! {
|
||||
__cx.virtual_child(
|
||||
|
||||
Reference in new issue
Block a user