soda_sol/
helpers.rs

1use crate::{structs, Error};
2use handlebars::{handlebars_helper, Handlebars};
3use structs::{InstructionType, TemplateHelper, IDL};
4
5pub(crate) fn create_handlebars_registry() -> Handlebars<'static> {
6    handlebars_helper!(snakecase: |name: String| name.chars().enumerate().fold(
7            "".to_string(),
8            |acc, (index, letter)| {
9                if letter.is_uppercase() {
10                    if index == 0 {
11                        format!("{}{}", acc, letter.to_lowercase())
12                    } else {
13                        format!("{}_{}", acc, letter.to_lowercase())
14                    }
15                } else {
16                    format!("{}{}", acc, letter)
17                }
18            }
19        )
20    );
21
22    handlebars_helper!(pascalcase: |name: String|{
23            let mut passcalcase_chars: Vec<char> = name.chars().collect();
24            if passcalcase_chars.is_empty() {
25                "".to_string()
26            } else {
27            let first: Vec<char> = passcalcase_chars[0].to_uppercase().to_string().chars().collect();
28            passcalcase_chars[0] = *first.first().unwrap_or(&' ');
29            let passcalcase: String = passcalcase_chars.into_iter().collect();
30            passcalcase
31            }
32        }
33    );
34
35    handlebars_helper!(type_from_account_field: |account_field_type: InstructionType| type_from_account_field_impl(account_field_type));
36
37    handlebars_helper!(debug_idl: |idl: IDL|serde_json::to_string(&idl).unwrap_or("".to_string()));
38
39    let mut handlebars = Handlebars::new();
40
41    handlebars.register_helper("snakecase", Box::new(snakecase));
42    handlebars.register_helper("pascalcase", Box::new(pascalcase));
43    handlebars.register_helper("type_from_account_field", Box::new(type_from_account_field));
44    handlebars.register_helper("debug_idl", Box::new(debug_idl));
45    handlebars
46}
47
48pub fn apply_user_helpers(
49    helpers: Vec<TemplateHelper>,
50    handlebars: &mut handlebars::Handlebars,
51) -> Result<(), Error> {
52    for TemplateHelper {
53        helper_name,
54        script,
55    } in helpers
56    {
57        match handlebars.register_script_helper(&helper_name, &script) {
58            Ok(_) => {}
59            Err(err) => {
60                return Err(Error::CustomError {
61                    message: format!("Error registering helper: {}", err),
62                })
63            }
64        }
65    }
66    Ok(())
67}
68
69fn type_from_account_field_impl(account_field_type:  InstructionType) -> String {
70    match account_field_type {
71        InstructionType::String => "String".to_string(),
72        InstructionType::U8 => "u8".to_string(),
73        InstructionType::U16 => "u16".to_string(),
74        InstructionType::U32 => "u32".to_string(),
75        InstructionType::U64 => "u64".to_string(),
76        InstructionType::U128 => "u128".to_string(),
77        InstructionType::Bool => "bool".to_string(),
78        InstructionType::Vec(content) => format!("Vec<{}>", type_from_account_field_impl(*content)),
79        InstructionType::Option(option) => format!("Option<{}>", type_from_account_field_impl(*option)),
80        InstructionType::Defined(defined) => defined,
81        InstructionType::Array(content, number) => format!("[{}; {}]", type_from_account_field_impl(*content), number),
82        InstructionType::Bytes => "Vec<u8>".to_string(),
83        InstructionType::I128 => "i128".to_string(),
84        InstructionType::I16 => "i16".to_string(),
85        InstructionType::I32 => "i32".to_string(),
86        InstructionType::I64 => "i64".to_string(),
87        InstructionType::I8 => "i8".to_string(),
88        InstructionType::Tuple(content) => {
89            let mut tuple = "(".to_string();
90            for (i, inner_content) in content.iter().enumerate() {
91                tuple.push_str(&type_from_account_field_impl(inner_content.clone()));
92                if i < content.iter().len() - 1 {
93                    tuple.push_str(", ");
94                }
95            }
96            tuple.push_str(")");
97            tuple
98        }
99        InstructionType::PublicKey => "Pubkey".to_string(),
100        InstructionType::pubkey => "Pubkey".to_string(),
101        InstructionType::HashMap(content_a, content_b) => format!("HashMap<{}, {}>", type_from_account_field_impl(*content_a), type_from_account_field_impl(*content_b)),
102        InstructionType::BTreeMap(content_a, content_b) => format!("BTreeMap<{}, {}>", type_from_account_field_impl(*content_a), type_from_account_field_impl(*content_b)),
103        InstructionType::HashSet(content) => format!("HashSet<{}>", type_from_account_field_impl(*content)),
104        InstructionType::BTreeSet(content) => format!("BTreeSet<{}>", type_from_account_field_impl(*content)),
105    }    
106}