trident_template/
template.rs

1use std::collections::HashMap;
2
3use convert_case::{Case, Casing};
4use trident_idl_spec::{Idl, IdlInstruction};
5
6use crate::process_program_id;
7
8pub(crate) struct ModDefinition {
9    pub module: syn::ItemMod,
10    pub use_statement: syn::ItemUse,
11}
12
13#[derive(Default)]
14pub struct Template {
15    pub(crate) instructions_mod: Vec<ModDefinition>,
16    pub(crate) instructions: HashMap<String, syn::File>,
17    pub(crate) transactions_mod: Vec<ModDefinition>,
18    pub(crate) transactions: HashMap<String, syn::File>,
19    pub(crate) fuzz_transactions: Vec<syn::Variant>,
20    pub(crate) account_storages: HashMap<String, syn::Field>,
21    pub(crate) test_fuzz: Option<syn::File>,
22    pub(crate) custom_types: Vec<syn::Item>,
23}
24
25impl Template {
26    pub fn create_template(&mut self, idls: &[Idl], lib_names: &[String]) {
27        let mut program_ids = HashMap::new();
28
29        for idl in idls {
30            // Assign program IDs to program names.
31            let program_name = idl.metadata.name.clone();
32            let program_id = idl.address.clone();
33
34            program_ids.insert(program_name, program_id);
35
36            self.process_idl(idl);
37        }
38
39        self.test_fuzz(&program_ids, lib_names);
40    }
41
42    fn process_idl(&mut self, idl: &Idl) {
43        let program_id = process_program_id(idl);
44
45        idl.instructions.iter().for_each(|instruction| {
46            self.process_instruction(&program_id, instruction);
47        });
48        self.custom_types(idl);
49    }
50    fn process_instruction(&mut self, program_id: &String, instruction: &IdlInstruction) {
51        self.fuzz_transaction_variant(instruction);
52        self.transaction(instruction);
53        self.instruction(instruction, program_id);
54        self.account_storage(instruction);
55    }
56    pub(crate) fn get_camel_identifier(&self, instruction: &IdlInstruction) -> String {
57        instruction.name.to_case(Case::UpperCamel)
58    }
59    pub(crate) fn get_snake_identifier(&self, instruction: &IdlInstruction) -> String {
60        instruction.name.to_case(Case::Snake)
61    }
62}