zits/to_typescript/
fns.rs

1use convert_case::{Case, Casing};
2use syn::{Attribute, FnArg, Ident, Pat, ReturnType};
3use crate::typescript::convert_type;
4use crate::{utils, ParseState};
5
6
7const HOLOCHAIN_CALLBACKS: [&str; 12] = [
8   "init", "entry_defs", "genesis_self_check",
9   "post_commit", "recv_remote_signal",
10   "validate",  "validate_create_link", "validate_delete_link",
11   "migrate_agent_open", "migrate_agent_close",
12   "get_zome_info", "get_dna_info", // Not callbacks, but must also be omitted
13];
14
15
16
17
18///
19impl super::ToTypescript for syn::ItemFn {
20
21   fn attrs(&self) -> Vec<Attribute> {self.attrs.clone()}
22   fn ident(&self) -> Ident {self.sig.ident.clone()}
23   fn kind(&self) -> &'static str {"fn"}
24
25   ///
26   fn convert_to_ts(self, state: &mut ParseState, _debug: bool, _uses_typeinterface: bool, is_blocking: Option<String>) {
27      //let comments = utils::get_comments(self.clone().attrs);
28      //write_comments(&mut state.fns_file, &comments, 0);
29
30      let fn_name = self.sig.ident.to_string();
31
32      /// Skip Holochain callbacks
33      if HOLOCHAIN_CALLBACKS.contains(&fn_name.as_str()) {
34         println!("[zits][info] Skipped callback '{}()'", fn_name);
35         return;
36      }
37      /// Make sure fn has Return type and at least one argument
38      let ReturnType::Type(_arrow, out_type) = self.sig.output else {
39         eprintln!("Failed to determine return type for function '{}()'", fn_name);
40         return;
41      };
42      let out_name = convert_type(&out_type, true).ts_type;
43
44      state.zome_proxy_output.push('\n');
45      state.zome_fn_names_output.push('\n');
46
47      let mut arg_name = "null".to_string();
48      let mut arg = "".to_string();
49      if let Some(FnArg::Typed(patty)) = self.sig.inputs.first() {
50          //println!("\n\npatty.{} = {:?}", fn_name, patty);
51          arg_name = match *patty.clone().pat {
52              Pat::Ident(pat_ident) => pat_ident.ident.to_string(),
53              Pat::Struct(_) => "input".to_string(),
54              _ => "null".to_string()
55          };
56
57          let arg_type = convert_type(&patty.ty, false).ts_type;
58
59          arg = if let Pat::Wild(_) = *patty.pat {
60              "".to_string()
61          } else {
62              format!("{}: {}", arg_name.to_case(Case::Camel), arg_type)
63          }
64      }
65
66      state.zome_proxy_output.push_str(&format!(
67         "  async {fn_name}{generics}({arg}): {out_name} {{\n"
68         , fn_name = fn_name.to_case(Case::Camel)
69         , generics = utils::extract_struct_generics(self.sig.generics.clone())
70      ));
71
72      let mut fn_delimiter = '(';
73      let call_fn = if let Some(entry_type) = is_blocking {
74         if entry_type == "" {
75            "callBlocking".to_string()
76         } else {
77            fn_delimiter = ',';
78            format!("callZomeBlockPostCommit('{}'", entry_type)
79         }
80      } else {
81         "call".to_string()
82      };
83
84      state.zome_proxy_output.push_str(&format!(
85             "    return this.{call_fn}{fn_delimiter}'{fn_name}', {arg_name});\n"
86             , arg_name = arg_name.to_case(Case::Camel)
87      ));
88
89      state.zome_proxy_output.push_str("  }\n");
90
91      /// zome_fn_names
92      state.zome_fn_names_output.push_str(&format!("\t\"{}\",", fn_name));
93   }
94}