feat: rec attrset
This commit is contained in:
@@ -17,7 +17,9 @@ use convert_case::{Case, Casing};
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::Span;
|
||||
use quote::{ToTokens, format_ident, quote};
|
||||
use syn::{FnArg, Item, ItemFn, ItemMod, Pat, PatType, Type, Visibility, parse_macro_input};
|
||||
use syn::{
|
||||
FnArg, Item, ItemFn, ItemMod, Pat, PatIdent, PatType, Type, Visibility, parse_macro_input,
|
||||
};
|
||||
|
||||
/// The implementation of the `#[builtins]` macro.
|
||||
pub fn builtins_impl(input: TokenStream) -> TokenStream {
|
||||
@@ -144,9 +146,15 @@ fn generate_primop_wrapper(
|
||||
|
||||
// Check if the first argument is a context `&mut Ctx`.
|
||||
let has_ctx = if let Some(FnArg::Typed(first_arg)) = user_args.peek() {
|
||||
if let Type::Reference(_) = *first_arg.ty {
|
||||
user_args.next(); // Consume the context argument
|
||||
true
|
||||
if let (Type::Reference(_), Pat::Ident(PatIdent { ident, .. })) =
|
||||
(&*first_arg.ty, &*first_arg.pat)
|
||||
{
|
||||
if ident == "ctx" {
|
||||
user_args.next();
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -163,17 +171,7 @@ fn generate_primop_wrapper(
|
||||
|
||||
// Generate code to unpack and convert arguments from the `Vec<Value>`.
|
||||
let arg_unpacks = arg_pats.iter().enumerate().map(|(i, arg)| {
|
||||
let arg_name = match &arg {
|
||||
FnArg::Typed(PatType { pat, .. }) => {
|
||||
if let Pat::Ident(pat_ident) = &**pat {
|
||||
pat_ident.ident.clone()
|
||||
} else {
|
||||
// Create a placeholder name if the pattern is not a simple ident.
|
||||
format_ident!("arg{}", i, span = Span::call_site())
|
||||
}
|
||||
}
|
||||
_ => format_ident!("arg{}", i, span = Span::call_site()),
|
||||
};
|
||||
let arg_name = format_ident!("_arg{}", i, span = Span::call_site());
|
||||
let arg_ty = match &arg {
|
||||
FnArg::Typed(PatType { ty, .. }) => ty,
|
||||
_ => unreachable!(),
|
||||
@@ -190,12 +188,8 @@ fn generate_primop_wrapper(
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, arg)| match &arg {
|
||||
FnArg::Typed(PatType { pat, .. }) => {
|
||||
if let Pat::Ident(pat_ident) = &**pat {
|
||||
pat_ident.ident.clone()
|
||||
} else {
|
||||
format_ident!("arg{}", i, span = Span::call_site())
|
||||
}
|
||||
FnArg::Typed(PatType { .. }) => {
|
||||
format_ident!("_arg{}", i, span = Span::call_site())
|
||||
}
|
||||
_ => unreachable!(),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user