allow specifying lifetimes for cpi

This commit is contained in:
Armani Ferrante 2022-02-07 09:47:27 -05:00
parent 07441fa656
commit 97adddf899
No known key found for this signature in database
GPG Key ID: D597A80BCF8E12B7
3 changed files with 47 additions and 2 deletions

View File

@ -70,9 +70,52 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
let sighash_arr = sighash(SIGHASH_GLOBAL_NAMESPACE, name); let sighash_arr = sighash(SIGHASH_GLOBAL_NAMESPACE, name);
let sighash_tts: proc_macro2::TokenStream = let sighash_tts: proc_macro2::TokenStream =
format!("{:?}", sighash_arr).parse().unwrap(); format!("{:?}", sighash_arr).parse().unwrap();
let (generics, generics_def) = {
let ty = &*ix.ctx.raw_arg.ty;
let generics = match ty {
syn::Type::Path(ty_path) => {
let segment = &ty_path.path.segments[0];
match &segment.arguments {
syn::PathArguments::AngleBracketed(bracket_args) => {
&bracket_args.args
}
_ => panic!("Invalid context"),
}
},
_ => panic!("Invalid context"),
};
// If the user doesn't provide lifetimes, make this
// assumption about the type.
if generics.len() == 1 {
(
quote! {
'_, '_, '_, 'info, #accounts_ident<'info>
},
quote! {
<'info>
}
)
}
// User provided lifetimes, so use them.
else {
let generics_def = &ix.raw_method.sig.generics;
(
quote! {
#generics
},
quote! {
#generics_def
}
)
}
};
println!("GENERICS: {:?}", crate::parser::tts_to_string(&generics));
quote! { quote! {
pub fn #method_name<'a, 'b, 'c, 'info>( pub fn #method_name #generics_def(
ctx: anchor_lang::context::CpiContext<'a, 'b, 'c, 'info, #accounts_ident<'info>>, ctx: anchor_lang::context::CpiContext<#generics>,
#(#args),* #(#args),*
) -> ProgramResult { ) -> ProgramResult {
let ix = { let ix = {

View File

@ -87,6 +87,7 @@ pub struct Ix {
pub args: Vec<IxArg>, pub args: Vec<IxArg>,
// The ident for the struct deriving Accounts. // The ident for the struct deriving Accounts.
pub anchor_ident: Ident, pub anchor_ident: Ident,
pub ctx: IxArg,
} }
#[derive(Debug)] #[derive(Debug)]

View File

@ -29,6 +29,7 @@ pub fn parse(program_mod: &syn::ItemMod) -> ParseResult<(Vec<Ix>, Option<Fallbac
ident: method.sig.ident.clone(), ident: method.sig.ident.clone(),
args, args,
anchor_ident, anchor_ident,
ctx,
}) })
}) })
.collect::<ParseResult<Vec<Ix>>>()?; .collect::<ParseResult<Vec<Ix>>>()?;