feat: Add more support for patterns and conditional match

This commit is contained in:
2025-01-11 15:52:13 -05:00
parent 0858e04c41
commit 820afa2171
3 changed files with 111 additions and 8 deletions

View File

@@ -64,7 +64,10 @@ enum LogicArg {
impl Parse for LogicArg {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
if input.peek(Token![for]) {
if input.peek3(Token![in]) {
let pat_fork = input.fork();
_ = pat_fork.parse::<Token![for]>()?;
if pat_fork.call(syn::Pat::parse_single).is_ok() && pat_fork.peek(Token![in]) {
input.parse().map(Self::ForIn)
} else {
input.parse().map(Self::ForIter)
@@ -263,28 +266,54 @@ impl ToTokens for Match {
struct MatchArm {
pattern: syn::Pat,
if_expr: Option<Value>,
args: Arguments,
}
impl Parse for MatchArm {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let pattern = input.call(syn::Pat::parse_multi)?;
let if_expr = if input.peek(Token![if]) {
_ = input.parse::<Token![if]>()?;
Some(input.parse()?)
} else {
None
};
_ = input.parse::<Token![=>]>()?;
let args = input.parse()?;
Ok(Self { pattern, args })
Ok(Self {
pattern,
if_expr,
args,
})
}
}
impl ToTokens for MatchArm {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let Self { pattern, args } = self;
let Self {
pattern,
if_expr,
args,
} = self;
tokens.extend(quote! {
#pattern => {
#args
}
});
tokens.extend(if_expr.as_ref().map_or_else(
|| {
quote! {
#pattern => {
#args
}
}
},
|if_expr| {
quote! {
#pattern if #if_expr => {
#args
}
}
},
));
}
}