feat: Add more support for patterns and conditional match
This commit is contained in:
45
src/cmd.rs
45
src/cmd.rs
@@ -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
|
||||
}
|
||||
}
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user