tsain_pattern/patterns/
props.rs1use super::*;
2
3pub type PropsPattern = Composition<Vec<(&'static str, &'static str)>>;
5
6impl PropsPattern {
7 pub fn list(&self) -> &Vec<(&'static str, &'static str)> {
8 &self.list
9 }
10
11 fn prop_names(&self) -> String {
13 self.list
14 .iter()
15 .map(|(n, _)| *n)
16 .collect::<Vec<_>>()
17 .join(", ")
18 }
19
20 fn prop_types(&self) -> String {
22 self.list
23 .iter()
24 .map(|(_, t)| *t)
25 .collect::<Vec<_>>()
26 .join(", ")
27 }
28
29 fn prop_name2types(&self) -> String {
31 self.list
32 .iter()
33 .map(|(n, t)| format!("{n}: {t}"))
34 .collect::<Vec<_>>()
35 .join(", ")
36 }
37}
38
39impl PropsPattern {
41 fn default_declaration_script(&self, var_id: Option<u32>) -> String {
42 let ts_name = &self.ts_name;
43 let prop_types = self.prop_types();
44 let type_args = crate::format_type_args(&self.type_args);
45
46 let brands_script = self.build_brands_script();
47
48 match var_id {
49 None => format!(r#"export type {ts_name}{type_args} = [{prop_types}]{brands_script};"#),
50 Some(var_id) => format!(
51 r#"export type {ts_name}{type_args} = [{var_id}, [{prop_types}]]{brands_script};"#
52 ),
53 }
54 }
55
56 fn default_constructor_name(&self) -> String {
57 format!("{}_", self.ts_name)
58 }
59
60 fn default_constructor_script(&self, var_id: Option<u32>) -> String {
61 let ts_name = &self.ts_name;
62 let type_args = crate::format_type_args(&self.type_args);
63 let constructor_name = self.default_constructor_name();
64
65 let prop_names = self.prop_names();
66 let prop_name2types = self.prop_name2types();
67
68 match var_id {
69 None => format!(
70 "export const {constructor_name} = {type_args}({prop_name2types}) => [{prop_names}] as {ts_name}{type_args};"
71 ),
72 Some(var_id) => format!(
73 "export const {constructor_name} = {type_args}({prop_name2types}) => [{var_id}, [{prop_names}]] as {ts_name}{type_args};"
74 ),
75 }
76 }
77
78 fn default_prop_getter_script(
79 &self,
80 prop_name: &str,
81 prop_type: &str,
82 prop_idx: usize,
83 is_variant: bool,
84 ) -> String {
85 let ts_name = &self.ts_name;
86 let type_args = crate::format_type_args(&self.type_args);
87
88 let mut script = format!("export const {ts_name}_{prop_name}_id: number = {prop_idx};\n");
90
91 let getter = match is_variant {
93 false => {
94 format!(
95 "export const {ts_name}_{prop_name} = {type_args}(v: {ts_name}{type_args}): {prop_type} => v[{prop_idx}];\n"
96 )
97 }
98 true => {
99 format!(
100 "export const {ts_name}_{prop_name} = {type_args}(v: {ts_name}{type_args}): {prop_type} => v[1][{prop_idx}];\n"
101 )
102 }
103 };
104 script.push_str(&getter);
105 return script;
106 }
107
108 fn default_prop_getters_script(&self, is_variant: bool) -> String {
109 self.list
110 .iter()
111 .enumerate()
112 .map(|(i, (name, ty))| self.default_prop_getter_script(name, ty, i, is_variant))
113 .collect::<Vec<_>>()
114 .join("\n")
115 }
116
117 pub(crate) fn default_as_variant_script(
118 &self,
119 enum_ts_name: &str,
120 enum_type_args: &str,
121 var_id: u32,
122 ) -> String {
123 let ts_name = self.ts_name;
124 let type_args = crate::format_type_args(&self.type_args);
125 format!(
126 "export const as{ts_name} = {enum_type_args}(e: {enum_ts_name}{enum_type_args}): {ts_name}{type_args} | undefined => e[0] == {var_id} ? e as {ts_name}{type_args} : undefined;"
127 )
128 }
129}
130
131impl PropsFormatter for DefaultPropsFormatter {
132 fn props_head_script(&self, props: &PropsPattern, var_id: Option<u32>) -> String {
133 let ts_name = &props.ts_name;
134 match var_id {
135 None => format!("// # Struct {ts_name}"),
136 Some(var_id) => format!("// ## Variant {var_id}: {ts_name}"),
137 }
138 }
139
140 fn props_script_list(
141 &self,
142 props: &PropsPattern,
143 var_id: Option<u32>,
144 ) -> Vec<(String, String)> {
145 vec![
146 (
147 format!("// 1. Type"),
149 props.default_declaration_script(var_id),
150 ),
151 (
152 format!("// 2. Constructor"),
154 props.default_constructor_script(var_id),
155 ),
156 (
157 format!("// 3. Getters"),
159 props.default_prop_getters_script(var_id.is_some()),
160 ),
161 ]
162 }
163
164 fn as_variant_script(
165 &self,
166 props: &PropsPattern,
167 enum_ts_name: &str,
168 enum_type_args: &str,
169 var_id: u32,
170 ) -> String {
171 props.default_as_variant_script(enum_ts_name, enum_type_args, var_id)
172 }
173}