1use heck::SnakeCase;
2use proc_macro2::TokenStream;
3use quote::{format_ident, quote};
4
5use super::{
6 common::{gen_print_section, get_idl_module_path, get_serde_json_module_path},
7 defined::gen_idl_type_def_struct,
8};
9
10pub fn gen_idl_print_fn_event(event_struct: &syn::ItemStruct) -> TokenStream {
11 let idl = get_idl_module_path();
12 let serde_json = get_serde_json_module_path();
13
14 let ident = &event_struct.ident;
15 let fn_name = format_ident!(
16 "__anchor_private_print_idl_event_{}",
17 ident.to_string().to_snake_case()
18 );
19 let idl_build_impl = impl_idl_build_event(event_struct);
20
21 let print_ts = gen_print_section(
22 "event",
23 quote! {
24 #serde_json::json!({
25 "event": event,
26 "types": types.into_values().collect::<Vec<_>>()
27 })
28 },
29 );
30
31 quote! {
32 #idl_build_impl
33
34 #[test]
35 pub fn #fn_name() {
36 let mut types: std::collections::BTreeMap<String, #idl::IdlTypeDef> =
37 std::collections::BTreeMap::new();
38 if let Some(event) = #ident::__anchor_private_gen_idl_event(&mut types) {
39 #print_ts
40 }
41 }
42 }
43}
44
45fn impl_idl_build_event(event_struct: &syn::ItemStruct) -> TokenStream {
47 let idl = get_idl_module_path();
48
49 let ident = &event_struct.ident;
50 let (impl_generics, ty_generics, where_clause) = event_struct.generics.split_for_impl();
51
52 let fn_body = match gen_idl_type_def_struct(event_struct) {
53 Ok((ts, defined)) => quote! {
54 #(
55 if let Some(ty) = <#defined>::create_type() {
56 types.insert(<#defined>::get_full_path(), ty);
57 <#defined>::insert_types(types);
58 }
59 );*
60
61 let ty = #ts;
62 let event = #idl::IdlEvent {
63 name: ty.name.clone(),
64 discriminator: Self::DISCRIMINATOR.into(),
65 };
66 types.insert(ty.name.clone(), ty);
67 Some(event)
68 },
69 _ => quote! { None },
70 };
71
72 quote! {
73 impl #impl_generics #ident #ty_generics #where_clause {
74 pub fn __anchor_private_gen_idl_event(
75 types: &mut std::collections::BTreeMap<String, #idl::IdlTypeDef>,
76 ) -> Option<#idl::IdlEvent> {
77 #fn_body
78 }
79 }
80 }
81}