anchor_syn/idl/
event.rs

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
45/// Generate IDL build impl for an event.
46fn 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}