mproto_codegen/codegen/
mod.rs1use genco::prelude::*;
2
3use crate::{ast::QualifiedIdentifier, Database};
4
5pub use codegen_cx::{
6 type_uses_param, type_uses_type_param, CodegenCx, ResolvedType, TypeParamBinding,
7 TypeParamBindings,
8};
9pub(crate) use type_base_len::{
10 enum_base_len, enum_variant_base_len, struct_base_len, type_base_len, TypeBaseLen,
11};
12
13mod codegen_cx;
14pub mod js;
15pub mod name_util;
16pub mod rust;
17mod type_base_len;
18
19pub trait MprotoLang {
20 type GencoLang: genco::lang::Lang;
21
22 fn associated_constant(type_name: &str, constant: &str) -> Tokens<Self::GencoLang>;
23
24 fn type_param_base_len(type_name: &str) -> Tokens<Self::GencoLang>;
26 fn const_fn_max() -> Tokens<Self::GencoLang>;
27 fn import_qualified(
28 db: &Database,
29 local_def_source: Option<&str>,
30 qualified_identifier: &QualifiedIdentifier,
31 ) -> Tokens<Self::GencoLang>;
32}
33
34#[derive(Debug, Eq, PartialEq)]
35pub enum MprotoJs {}
36#[derive(Debug, Eq, PartialEq)]
37pub enum MprotoRust {}
38
39impl MprotoLang for MprotoJs {
40 type GencoLang = genco::lang::JavaScript;
41
42 fn associated_constant(type_name: &str, constant: &str) -> Tokens<Self::GencoLang> {
43 quote! { $type_name.$constant }
44 }
45
46 fn type_param_base_len(type_name: &str) -> Tokens<Self::GencoLang> {
47 quote! { this.$(type_name)Encoder.baseLength() }
48 }
49
50 fn const_fn_max() -> Tokens<Self::GencoLang> {
51 quote! { Math.max }
52 }
53
54 fn import_qualified(
55 db: &Database,
56 local_def_source: Option<&str>,
57 qualified_identifier: &QualifiedIdentifier,
58 ) -> Tokens<Self::GencoLang> {
59 if let Some(module) = &qualified_identifier.module {
60 let lib_suffix = db
62 .lookup_module_lib_suffix(module)
63 .expect(&format!("module '{module}' not found"));
65 quote! {
66 $(genco::lang::js::import(
67 format!("{module}-{lib_suffix}").as_ref(),
68 &qualified_identifier.name,
69 ))
70 }
71 } else if let Some(local_def_source) = local_def_source {
72 quote! {
74 $(genco::lang::js::import(
75 local_def_source,
76 &qualified_identifier.name,
77 ))
78 }
79 } else {
80 quote! { $(&qualified_identifier.name) }
82 }
83 }
84}
85
86impl MprotoLang for MprotoRust {
87 type GencoLang = genco::lang::Rust;
88
89 fn associated_constant(type_name: &str, constant: &str) -> Tokens<Self::GencoLang> {
90 quote! { $type_name::$constant }
91 }
92
93 fn type_param_base_len(type_name: &str) -> Tokens<Self::GencoLang> {
94 Self::associated_constant(type_name, "BASE_LEN")
95 }
96
97 fn const_fn_max() -> Tokens<Self::GencoLang> {
98 quote! { $(genco::lang::rust::import("mproto", "max")) }
99 }
100
101 fn import_qualified(
102 db: &Database,
103 local_def_source: Option<&str>,
104 qualified_identifier: &QualifiedIdentifier,
105 ) -> Tokens<Self::GencoLang> {
106 if let Some(module) = &qualified_identifier.module {
107 let lib_suffix = db
109 .lookup_module_lib_suffix(module)
110 .expect(&format!("module '{module}' not found"));
112 quote! {
113 $(
114 genco::lang::rust::import(
115 &format!("{module}_{lib_suffix}"),
116 &qualified_identifier.name,
117 )
118 .qualified()
119 )
120 }
121 } else if let Some(local_def_source) = local_def_source {
122 quote! {
124 $(genco::lang::rust::import(
125 local_def_source,
126 &qualified_identifier.name,
127 ))
128 }
129 } else {
130 quote! { $(&qualified_identifier.name) }
132 }
133 }
134}