|
1 | | -use std::collections::BTreeMap; |
2 | | - |
3 | | -use anchor_syn::idl::{IdlEvent, IdlField, IdlTypeDefinition}; |
| 1 | +use crate::{ |
| 2 | + fields::{generate_struct_fields, get_idl_defined_fields_as_slice}, |
| 3 | + get_field_list_properties, StructOpts, |
| 4 | +}; |
| 5 | +use anchor_lang_idl_spec::{IdlDefinedFields, IdlEvent, IdlTypeDef}; |
4 | 6 | use proc_macro2::TokenStream; |
5 | 7 | use quote::{format_ident, quote}; |
6 | | -use sha2::{Digest, Sha256}; |
| 8 | +use std::collections::BTreeMap; |
| 9 | +use syn::Ident; |
7 | 10 |
|
8 | | -use crate::{generate_struct, StructOpts}; |
| 11 | +/// Generates a struct. |
| 12 | +pub fn generate_event( |
| 13 | + defs: &[IdlTypeDef], |
| 14 | + struct_name: &Ident, |
| 15 | + fields: &Option<IdlDefinedFields>, |
| 16 | +) -> TokenStream { |
| 17 | + let fields_rendered = generate_struct_fields(fields); |
| 18 | + let props = get_field_list_properties(defs, get_idl_defined_fields_as_slice(fields)); |
| 19 | + |
| 20 | + let derive_default = if props.can_derive_default { |
| 21 | + quote! { |
| 22 | + #[derive(Default)] |
| 23 | + } |
| 24 | + } else { |
| 25 | + quote! {} |
| 26 | + }; |
| 27 | + |
| 28 | + quote! { |
| 29 | + #[event] |
| 30 | + #[derive(Debug)] |
| 31 | + #derive_default |
| 32 | + pub struct #struct_name { |
| 33 | + #fields_rendered |
| 34 | + } |
| 35 | + } |
| 36 | +} |
9 | 37 |
|
10 | 38 | /// Generates event structs. |
11 | 39 | pub fn generate_events( |
12 | | - events: Option<&[IdlEvent]>, |
13 | | - typedefs: &[IdlTypeDefinition], |
| 40 | + events: &[IdlEvent], |
| 41 | + typedefs: &[IdlTypeDef], |
14 | 42 | struct_opts: &BTreeMap<String, StructOpts>, |
15 | 43 | ) -> TokenStream { |
16 | | - match events { |
17 | | - Some(events) => { |
18 | | - let defined = events.iter().map(|def| { |
19 | | - let struct_name = format_ident!("{}", def.name); |
20 | | - let opts = struct_opts.get(&def.name).copied().unwrap_or_default(); |
21 | | - |
22 | | - let discriminator: proc_macro2::TokenStream = { |
23 | | - let discriminator_preimage = format!("event:{}", struct_name); |
24 | | - let mut discriminator = [0u8; 8]; |
25 | | - let mut hash = Sha256::default(); |
26 | | - hash.update(discriminator_preimage.as_bytes()); |
27 | | - discriminator.copy_from_slice(&hash.finalize()[..8]); |
28 | | - format!("{:?}", discriminator).parse().unwrap() |
29 | | - }; |
30 | | - |
31 | | - let fields = def |
32 | | - .fields |
33 | | - .iter() |
34 | | - .map(|f| IdlField { |
35 | | - name: f.name.clone(), |
36 | | - ty: f.ty.clone(), |
37 | | - }) |
38 | | - .collect::<Vec<_>>(); |
39 | | - |
40 | | - let struct_ts = generate_struct(&typedefs, &struct_name, &fields, opts); |
41 | | - |
42 | | - quote! { |
43 | | - #struct_ts |
44 | | - |
45 | | - impl anchor_lang::Discriminator for #struct_name { |
46 | | - const DISCRIMINATOR: [u8; 8] = #discriminator; |
47 | | - fn discriminator() -> [u8; 8] { |
48 | | - #discriminator |
49 | | - } |
50 | | - } |
51 | | - } |
52 | | - }); |
53 | | - quote! { |
54 | | - #(#defined)* |
| 44 | + let defined = events.iter().map(|def| { |
| 45 | + let struct_name = format_ident!("{}", def.name); |
| 46 | + let opts = struct_opts.get(&def.name).copied().unwrap_or_default(); |
| 47 | + if opts.skip { |
| 48 | + quote! {} |
| 49 | + } else { |
| 50 | + let typedef = typedefs.iter().find(|d| d.name == def.name).unwrap(); |
| 51 | + if let anchor_lang_idl_spec::IdlTypeDefTy::Struct { fields } = &typedef.ty { |
| 52 | + generate_event(typedefs, &struct_name, fields) |
| 53 | + } else { |
| 54 | + quote! {} |
55 | 55 | } |
56 | 56 | } |
57 | | - None => quote!(), |
| 57 | + }); |
| 58 | + quote! { |
| 59 | + #(#defined)* |
58 | 60 | } |
59 | 61 | } |
0 commit comments