trident_syn/codegen/
trident_transaction.rs

1use proc_macro2::TokenStream;
2use quote::quote;
3use quote::ToTokens;
4
5use crate::types::trident_transaction::TridentTransactionStruct;
6
7impl ToTokens for TridentTransactionStruct {
8    fn to_tokens(&self, tokens: &mut TokenStream) {
9        let name = &self.ident;
10        let field_idents = self.fields.iter().map(|f| &f.ident).collect::<Vec<_>>();
11
12        // Generate the name implementation
13        let name_impl = quote! { stringify!(#name).to_string() };
14
15        // Generate instruction blocks for each field
16        let instruction_blocks = self.fields.iter().map(|f| {
17            let field_ident = &f.ident;
18            quote! {
19                {
20                    self.#field_ident.set_data(trident, fuzz_accounts);
21                    self.#field_ident.resolve_accounts(trident, fuzz_accounts);
22                    self.#field_ident.set_accounts(trident, fuzz_accounts);
23                    self.#field_ident.set_remaining_accounts(trident, fuzz_accounts);
24                }
25            }
26        });
27
28        let expanded = quote! {
29            // Implement the getters trait
30            impl TransactionGetters for #name {
31                fn get_transaction_name(&self) -> String {
32                    #name_impl
33                }
34
35                fn get_instruction_discriminators(&self) -> Vec<Vec<u8>> {
36                    vec![
37                        #(self.#field_idents.get_discriminator()),*
38                    ]
39                }
40
41                fn get_instruction_program_ids(&self) -> Vec<solana_sdk::pubkey::Pubkey> {
42                    vec![
43                        #(self.#field_idents.get_program_id()),*
44                    ]
45                }
46
47                fn get_instruction_data(
48                    &mut self,
49                    client: &mut impl FuzzClient,
50                ) -> Vec<Vec<u8>> {
51                    vec![
52                        #(borsh::to_vec(&self.#field_idents.data).unwrap()),*
53                    ]
54                }
55
56                fn get_instruction_accounts(
57                    &mut self,
58                    client: &mut impl FuzzClient,
59                ) -> Vec<Vec<AccountMeta>> {
60                    vec![
61                        #(self.#field_idents.to_account_metas()),*
62                    ]
63                }
64            }
65
66            // Implement the setters trait
67            impl TransactionSetters for #name {
68                fn set_snapshot_before(
69                    &mut self,
70                    client: &mut impl FuzzClient,
71                ) {
72                    #(self.#field_idents.set_snapshot_before(client);)*
73                }
74
75                fn set_snapshot_after(
76                    &mut self,
77                    client: &mut impl FuzzClient,
78                ) {
79                    #(self.#field_idents.set_snapshot_after(client);)*
80                }
81
82                fn set_instructions(
83                    &mut self,
84                    trident: &mut Trident,
85                    fuzz_accounts: &mut Self::IxAccounts,
86                ) {
87                    #(#instruction_blocks)*
88                }
89            }
90
91        };
92
93        tokens.extend(expanded);
94    }
95}