78 lines
2.7 KiB
Rust
78 lines
2.7 KiB
Rust
use crate::codegen::program::common::*;
|
|
use crate::parser;
|
|
use crate::Program;
|
|
use heck::CamelCase;
|
|
use quote::quote;
|
|
|
|
pub fn generate(program: &Program) -> proc_macro2::TokenStream {
|
|
let variants: Vec<proc_macro2::TokenStream> = program
|
|
.ixs
|
|
.iter()
|
|
.map(|ix| {
|
|
let name = &ix.raw_method.sig.ident.to_string();
|
|
let ix_name_camel =
|
|
proc_macro2::Ident::new(&name.to_camel_case(), ix.raw_method.sig.ident.span());
|
|
let raw_args: Vec<proc_macro2::TokenStream> = ix
|
|
.args
|
|
.iter()
|
|
.map(|arg| {
|
|
format!("pub {}", parser::tts_to_string(&arg.raw_arg))
|
|
.parse()
|
|
.unwrap()
|
|
})
|
|
.collect();
|
|
let ix_data_trait = {
|
|
let sighash_arr = sighash(SIGHASH_GLOBAL_NAMESPACE, name);
|
|
let sighash_tts: proc_macro2::TokenStream =
|
|
format!("{:?}", sighash_arr).parse().unwrap();
|
|
quote! {
|
|
impl anchor_lang::Discriminator for #ix_name_camel {
|
|
const DISCRIMINATOR: [u8; 8] = #sighash_tts;
|
|
}
|
|
impl anchor_lang::InstructionData for #ix_name_camel {}
|
|
impl anchor_lang::Owner for #ix_name_camel {
|
|
fn owner() -> Pubkey {
|
|
ID
|
|
}
|
|
}
|
|
}
|
|
};
|
|
// If no args, output a "unit" variant instead of a struct variant.
|
|
if ix.args.is_empty() {
|
|
quote! {
|
|
/// Instruction.
|
|
#[derive(AnchorSerialize, AnchorDeserialize)]
|
|
pub struct #ix_name_camel;
|
|
|
|
#ix_data_trait
|
|
}
|
|
} else {
|
|
quote! {
|
|
/// Instruction.
|
|
#[derive(AnchorSerialize, AnchorDeserialize)]
|
|
pub struct #ix_name_camel {
|
|
#(#raw_args),*
|
|
}
|
|
|
|
#ix_data_trait
|
|
}
|
|
}
|
|
})
|
|
.collect();
|
|
|
|
quote! {
|
|
/// An Anchor generated module containing the program's set of
|
|
/// instructions, where each method handler in the `#[program]` mod is
|
|
/// associated with a struct defining the input arguments to the
|
|
/// method. These should be used directly, when one wants to serialize
|
|
/// Anchor instruction data, for example, when speciying
|
|
/// instructions on a client.
|
|
pub mod instruction {
|
|
use super::*;
|
|
|
|
|
|
#(#variants)*
|
|
}
|
|
}
|
|
}
|