use heck::SnakeCase;
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use super::{
common::{gen_print_section, get_idl_module_path, get_serde_json_module_path},
defined::gen_idl_type_def_struct,
};
pub fn gen_idl_print_fn_event(event_struct: &syn::ItemStruct) -> TokenStream {
let idl = get_idl_module_path();
let serde_json = get_serde_json_module_path();
let ident = &event_struct.ident;
let fn_name = format_ident!(
"__anchor_private_print_idl_event_{}",
ident.to_string().to_snake_case()
);
let idl_build_impl = impl_idl_build_event(event_struct);
let print_ts = gen_print_section(
"event",
quote! {
#serde_json::json!({
"event": event,
"types": types.into_values().collect::<Vec<_>>()
})
},
);
quote! {
#idl_build_impl
#[test]
pub fn #fn_name() {
let mut types: std::collections::BTreeMap<String, #idl::IdlTypeDef> =
std::collections::BTreeMap::new();
if let Some(event) = #ident::__anchor_private_gen_idl_event(&mut types) {
#print_ts
}
}
}
}
fn impl_idl_build_event(event_struct: &syn::ItemStruct) -> TokenStream {
let idl = get_idl_module_path();
let ident = &event_struct.ident;
let (impl_generics, ty_generics, where_clause) = event_struct.generics.split_for_impl();
let fn_body = match gen_idl_type_def_struct(event_struct) {
Ok((ts, defined)) => quote! {
#(
if let Some(ty) = <#defined>::create_type() {
types.insert(<#defined>::get_full_path(), ty);
<#defined>::insert_types(types);
}
);*
let ty = #ts;
let event = #idl::IdlEvent {
name: ty.name.clone(),
discriminator: <Self as anchor_lang::Discriminator>::DISCRIMINATOR.into(),
};
types.insert(ty.name.clone(), ty);
Some(event)
},
_ => quote! { None },
};
quote! {
impl #impl_generics #ident #ty_generics #where_clause {
pub fn __anchor_private_gen_idl_event(
types: &mut std::collections::BTreeMap<String, #idl::IdlTypeDef>,
) -> Option<#idl::IdlEvent> {
#fn_body
}
}
}
}