modrpc_codegen/codegen/js/
mod.rs1use genco::prelude::*;
2use mproto_codegen::codegen::{js::js_type_param_list, name_util::snake_to_camel_case};
3
4use crate::{Database, ast::Interface};
5
6pub use project::{js_project_gen, js_proto_package_gen};
7
8pub mod project;
9
10pub fn js_wit_object_class(
11 db: &Database,
12 object_interface: &Interface,
13 object_role_name: &String,
14) -> js::Tokens {
15 let mproto_cx = &mproto_codegen::codegen::CodegenCx::new_with_type_params(
16 db.mproto_db(),
17 Some("./proto"),
18 true,
19 &object_interface.type_params,
20 );
21
22 let mut method_fields: js::Tokens = quote! {};
23 let mut method_args: js::Tokens = quote! {};
24 let mut method_set_fields: js::Tokens = quote! {};
25 let mut methods: js::Tokens = quote! {};
26
27 for methods_list in &object_interface.methods {
28 if !methods_list.roles.contains(object_role_name) {
29 continue;
30 }
31
32 for method in &methods_list.methods {
33 let input_type =
34 mproto_codegen::codegen::js::js_type_tokens(mproto_cx, &method.input_ty);
35 let output_type =
36 mproto_codegen::codegen::js::js_type_tokens(mproto_cx, &method.output_ty);
37
38 let input_encoder =
39 mproto_codegen::codegen::js::js_type_encoder(mproto_cx, &method.input_ty);
40 let output_encoder =
41 mproto_codegen::codegen::js::js_type_encoder(mproto_cx, &method.output_ty);
42
43 let method_name_camel = &snake_to_camel_case(&method.name);
44
45 if method.is_async {
46 method_fields = quote! {
47 $method_fields
48 private $(method_name_camel)Wasm: (input: Uint8Array) => any;
49 private $(method_name_camel)Resolvers: { [id: number] : (r: any) => void };
50 };
51
52 method_args = quote! {
53 $method_args
54 $(method_name_camel)Wasm: (input: Uint8Array) => any,
55 $(method_name_camel)Resolvers: { [id: number] : (r: any) => void },
56 };
57
58 method_set_fields = quote! {
59 $method_set_fields
60 this.$(method_name_camel)Wasm = $(method_name_camel)Wasm;
61 this.$(method_name_camel)Resolvers = $(method_name_camel)Resolvers;
62 };
63
64 methods = quote! {
65 $methods
66
67 public async $method_name_camel(input: $input_type): Promise<$output_type> {
68 const inputBuf = new Uint8Array(mproto.encodeValue($input_encoder, input));
69
70 const id = this.$(method_name_camel)Wasm(inputBuf);
71 const promise: Promise<any> = new Promise(resolve => {
72 this.$(method_name_camel)Resolvers[id] = resolve;
73 });
74
75 const outputBuf = await promise;
76 return mproto.decodeValue($output_encoder, outputBuf.buffer);
77 }
78 };
79 }
80 }
81 }
82
83 let mut type_param_encoder_fields: js::Tokens = quote! {};
84 let mut type_param_encoder_args: js::Tokens = quote! {};
85 let mut type_param_encoder_set_fields: js::Tokens = quote! {};
86
87 for type_param in &object_interface.type_params {
88 let type_param_name = type_param;
89 type_param_encoder_fields = quote! {
90 $type_param_encoder_fields
91 private $(type_param_name)Encoder: mproto.EncoderDecoder<$(type_param_name)>;
92 };
93 type_param_encoder_args = quote! {
94 $type_param_encoder_args
95 $(type_param_name)Encoder: mproto.EncoderDecoder<$(type_param_name)>,
96 };
97 type_param_encoder_set_fields = quote! {
98 $type_param_encoder_set_fields
99 this.$(type_param_name)Encoder = $(type_param_name)Encoder;
100 };
101 }
102
103 let object_interface_role_name = &format!("{}{}", object_interface.name, object_role_name);
104 let type_params_list = js_type_param_list(&object_interface.type_params);
105
106 quote! {
107 class $object_interface_role_name$(type_params_list) {
108 $type_param_encoder_fields
109 $method_fields
110
111 constructor(
112 $type_param_encoder_args
113 $method_args
114 ) {
115 $type_param_encoder_set_fields
116 $method_set_fields
117 }
118
119 $methods
120 }
121 }
122}
123
124pub fn js_interface_init_state_tokens(db: &mut Database, interface: &Interface) -> js::Tokens {
125 let init_state_struct = crate::codegen::interface_init_state(db, interface);
126 let init_state_struct_id = db
127 .mproto_db_mut()
128 .local_mut()
129 .new_type_def(init_state_struct);
130
131 quote! {
132 $(mproto_codegen::codegen::js::js_type_def(
133 &mproto_codegen::codegen::CodegenCx::new(db.mproto_db(), None, true),
134 db.mproto_db().local().type_def(init_state_struct_id)
135 ))
136 }
137}