TypeScript_Rust_Compiler/
types.rs1use crate::ast::*;
4use crate::error::Result;
5use std::collections::HashMap;
6
7pub struct TypeMapper {
9 type_mappings: HashMap<String, String>,
11 generics: Vec<String>,
13 runtime: bool,
15}
16
17fn extract_struct_name(code: &str) -> String {
19 if let Some(start) = code.find("struct ") {
20 if let Some(end) = code[start + 7..].find(" {") {
21 return code[start + 7..start + 7 + end].to_string();
22 }
23 }
24 "Unknown".to_string()
25}
26
27impl TypeMapper {
28 pub fn new(runtime: bool) -> Self {
30 let mut type_mappings = HashMap::new();
31
32 type_mappings.insert("string".to_string(), "String".to_string());
34 type_mappings.insert("number".to_string(), "f64".to_string());
35 type_mappings.insert("boolean".to_string(), "bool".to_string());
36 type_mappings.insert("void".to_string(), "()".to_string());
37 type_mappings.insert("never".to_string(), "!".to_string());
38 type_mappings.insert("any".to_string(), "Box<dyn Any>".to_string());
39 type_mappings.insert("unknown".to_string(), "Box<dyn Any>".to_string());
40 type_mappings.insert("null".to_string(), "Option<()>".to_string());
41 type_mappings.insert("undefined".to_string(), "Option<()>".to_string());
42 type_mappings.insert("object".to_string(), "Box<dyn Any>".to_string());
43 type_mappings.insert("symbol".to_string(), "Symbol".to_string());
44 type_mappings.insert("bigint".to_string(), "i64".to_string());
45
46 Self {
47 type_mappings,
48 generics: Vec::new(),
49 runtime,
50 }
51 }
52
53 pub fn map_type(&mut self, ts_type: &Type) -> Result<String> {
55 match ts_type {
56 Type::String => Ok("String".to_string()),
58 Type::Number => Ok("f64".to_string()),
59 Type::Boolean => Ok("bool".to_string()),
60 Type::Any => {
61 if self.runtime {
62 Ok("Box<dyn Any>".to_string())
63 } else {
64 Ok("serde_json::Value".to_string())
65 }
66 }
67 Type::Void => Ok("()".to_string()),
68 Type::Never => Ok("!".to_string()),
69 Type::Unknown => {
70 if self.runtime {
71 Ok("Box<dyn Any>".to_string())
72 } else {
73 Ok("serde_json::Value".to_string())
74 }
75 }
76 Type::Null => Ok("Option<()>".to_string()),
77 Type::Undefined => Ok("Option<()>".to_string()),
78 Type::Object => {
79 if self.runtime {
80 Ok("Box<dyn Any>".to_string())
81 } else {
82 Ok("serde_json::Value".to_string())
83 }
84 }
85 Type::Symbol => Ok("Symbol".to_string()),
86 Type::BigInt => Ok("i64".to_string()),
87
88 Type::Named(name) => self.map_named_type(name),
90 Type::Qualified(qualified) => self.map_qualified_type(qualified),
91
92 Type::Generic(generic) => self.map_generic_type(generic),
94 Type::GenericNamed {
95 name,
96 type_arguments,
97 } => {
98 let rust_name = self.map_named_type(name)?;
99 if type_arguments.is_empty() {
100 Ok(rust_name)
101 } else {
102 let param_types: Result<Vec<String>> = type_arguments
103 .iter()
104 .map(|arg| self.map_type(arg))
105 .collect();
106 let param_types = param_types?;
107 Ok(format!("{}<{}>", rust_name, param_types.join(", ")))
108 }
109 }
110
111 Type::Union { left, right } => {
113 let left_type = self.map_type(left)?;
114 let right_type = self.map_type(right)?;
115 Ok(format!("Union<{}, {}>", left_type, right_type))
116 }
117 Type::Intersection { left, right } => {
118 let left_type = self.map_type(left)?;
121 let right_type = self.map_type(right)?;
122
123 if left_type.starts_with("#[derive") && right_type.starts_with("#[derive") {
125 let left_struct = extract_struct_name(&left_type);
127 let right_struct = extract_struct_name(&right_type);
128 Ok(format!("{}And{}", left_struct, right_struct))
129 } else {
130 Ok(format!("Intersection<{}, {}>", left_type, right_type))
131 }
132 }
133
134
135 Type::Array(element_type) => {
137 let element_rust = self.map_type(element_type)?;
138 Ok(format!("Vec<{}>", element_rust))
139 }
140
141 Type::Tuple(types) => self.map_tuple_type(types),
143
144 Type::Function(func_type) => self.map_function_type(func_type),
146
147 Type::ObjectType(obj_type) => self.map_object_type(obj_type),
149
150 Type::IndexSignature(index_sig) => self.map_index_signature(index_sig),
152
153 Type::Mapped(mapped) => self.map_mapped_type(mapped),
155
156 Type::Conditional(conditional) => self.map_conditional_type(conditional),
158
159 Type::TemplateLiteral(template) => self.map_template_literal_type(template),
161
162 Type::Parenthesized(inner) => self.map_type(inner),
164
165 Type::TypeQuery(query) => self.map_type_query(query),
167
168 Type::Import(import) => self.map_import_type(import),
170 }
171 }
172
173 fn map_named_type(&self, name: &str) -> Result<String> {
175 if let Some(mapped) = self.type_mappings.get(name) {
176 Ok(mapped.clone())
177 } else {
178 Ok(self.to_pascal_case(name))
180 }
181 }
182
183 fn map_qualified_type(&mut self, qualified: &QualifiedTypeName) -> Result<String> {
185 let left = self.map_type(&qualified.left)?;
186 Ok(format!("{}::{}", left, qualified.right))
187 }
188
189 fn map_generic_type(&mut self, generic: &GenericType) -> Result<String> {
191 let base_type = self.map_type(&generic.type_)?;
192 let type_args: Result<Vec<String>> = generic
193 .type_arguments
194 .iter()
195 .map(|t| self.map_type(t))
196 .collect();
197 let type_args = type_args?;
198
199 if type_args.is_empty() {
200 Ok(base_type)
201 } else {
202 match base_type.as_str() {
204 "Array" => {
205 if type_args.len() == 1 {
206 Ok(format!("Vec<{}>", type_args[0]))
207 } else {
208 Ok(format!("Vec<{}>", type_args.join(", ")))
209 }
210 }
211 "Promise" => {
212 if type_args.len() == 1 {
213 Ok(format!("std::pin::Pin<Box<dyn std::future::Future<Output = {}>>>", type_args[0]))
214 } else {
215 Ok("Box<dyn std::future::Future<Output = ()>>".to_string())
216 }
217 }
218 "Map" | "Record" => {
219 if type_args.len() == 2 {
220 Ok(format!("std::collections::HashMap<{}, {}>", type_args[0], type_args[1]))
221 } else {
222 Ok("std::collections::HashMap<Box<dyn Any>, Box<dyn Any>>".to_string())
223 }
224 }
225 "Set" => {
226 if type_args.len() == 1 {
227 Ok(format!("std::collections::HashSet<{}>", type_args[0]))
228 } else {
229 Ok("std::collections::HashSet<Box<dyn Any>>".to_string())
230 }
231 }
232 "Partial" | "Required" | "Readonly" | "Pick" | "Omit" => {
233 if self.runtime {
235 Ok("Box<dyn Any>".to_string())
236 } else {
237 Ok(base_type)
238 }
239 }
240 _ => {
241 Ok(format!("{}<{}>", base_type, type_args.join(", ")))
242 }
243 }
244 }
245 }
246
247
248 fn map_tuple_type(&mut self, types: &[Type]) -> Result<String> {
250 if types.is_empty() {
251 return Ok("()".to_string());
252 }
253
254 let rust_types: Result<Vec<String>> = types.iter().map(|t| self.map_type(t)).collect();
255 let rust_types = rust_types?;
256
257 Ok(format!("({})", rust_types.join(", ")))
258 }
259
260 fn map_function_type(&mut self, func_type: &FunctionType) -> Result<String> {
262 let params: Result<Vec<String>> = func_type
263 .parameters
264 .iter()
265 .map(|param| {
266 let param_type = if let Some(ref t) = param.type_ {
267 self.map_type(t)?
268 } else {
269 "Box<dyn Any>".to_string()
270 };
271 Ok(format!("{}: {}", param.name, param_type))
272 })
273 .collect();
274 let params = params?;
275
276 let return_type = self.map_type(&func_type.return_type)?;
277
278 Ok(format!("fn({}) -> {}", params.join(", "), return_type))
279 }
280
281 fn map_object_type(&mut self, obj_type: &ObjectType) -> Result<String> {
283 let mut struct_fields = Vec::new();
284
285 for member in &obj_type.members {
286 match member {
287 ObjectTypeMember::Property(prop) => {
288 let field_type = if let Some(ref t) = prop.type_ {
289 self.map_type(t)?
290 } else {
291 "Box<dyn Any>".to_string()
292 };
293
294 let field_name = if prop.optional {
295 format!("{}: Option<{}>", prop.name, field_type)
296 } else {
297 format!("{}: {}", prop.name, field_type)
298 };
299
300 struct_fields.push(field_name);
301 }
302 ObjectTypeMember::Method(method) => {
303 let params: Result<Vec<String>> = method
305 .parameters
306 .iter()
307 .map(|param| {
308 let param_type = if let Some(ref t) = param.type_ {
309 self.map_type(t)?
310 } else {
311 "Box<dyn Any>".to_string()
312 };
313 Ok(format!("{}: {}", param.name, param_type))
314 })
315 .collect();
316 let params = params?;
317
318 let return_type = if let Some(ref t) = method.return_type {
319 self.map_type(t)?
320 } else {
321 "()".to_string()
322 };
323
324 struct_fields.push(format!(
325 "fn {}({}) -> {}",
326 method.name,
327 params.join(", "),
328 return_type
329 ));
330 }
331 _ => {
332 }
334 }
335 }
336
337 let struct_name = format!("ObjectType_{}", struct_fields.len());
339 Ok(format!(
340 "#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct {} {{\n {}\n}}",
341 struct_name,
342 struct_fields.join(",\n ")
343 ))
344 }
345
346 fn map_index_signature(&mut self, index_sig: &IndexSignature) -> Result<String> {
348 let key_type = self.map_type(
349 &index_sig
350 .parameter
351 .type_
352 .as_ref()
353 .map_or(Type::String, |v| *v.clone()),
354 )?;
355 let value_type = self.map_type(&index_sig.type_)?;
356 Ok(format!("HashMap<{}, {}>", key_type, value_type))
357 }
358
359 fn map_mapped_type(&mut self, mapped: &MappedType) -> Result<String> {
361 let key_type = self.map_type(
363 &mapped
364 .type_parameter
365 .constraint
366 .as_ref()
367 .map_or(Type::String, |v| *v.clone()),
368 )?;
369 let value_type = self.map_type(&mapped.type_)?;
370 Ok(format!("HashMap<{}, {}>", key_type, value_type))
371 }
372
373 fn map_conditional_type(&mut self, conditional: &ConditionalType) -> Result<String> {
375 let check_type = self.map_type(&conditional.check_type)?;
377 let extends_type = self.map_type(&conditional.extends_type)?;
378 let _true_type = self.map_type(&conditional.true_type)?;
379 let _false_type = self.map_type(&conditional.false_type)?;
380
381 Ok(format!(
382 "trait ConditionalType {{\n type Output: PartialEq<{}>;\n fn condition<{}>() -> Self::Output;\n}}",
383 extends_type, check_type
384 ))
385 }
386
387 fn map_template_literal_type(&mut self, template: &TemplateLiteralType) -> Result<String> {
389 Ok(format!("\"{}\"", template.head))
391 }
392
393 fn map_type_query(&mut self, _query: &TypeQuery) -> Result<String> {
395 Ok("TypeQuery".to_string())
397 }
398
399 fn map_import_type(&mut self, import: &ImportType) -> Result<String> {
401 let base_type = self.map_type(&import.argument)?;
402 if let Some(ref qualifier) = import.qualifier {
403 Ok(format!("{}::{}", base_type, qualifier))
404 } else {
405 Ok(base_type)
406 }
407 }
408
409 fn to_pascal_case(&self, s: &str) -> String {
411 let mut result = String::new();
412 let mut capitalize = true;
413
414 for ch in s.chars() {
415 if ch == '_' || ch == '-' {
416 capitalize = true;
417 } else if capitalize {
418 result.push(ch.to_uppercase().next().unwrap_or(ch));
419 capitalize = false;
420 } else {
421 result.push(ch);
422 }
423 }
424
425 result
426 }
427
428 pub fn add_generic(&mut self, name: String) {
430 self.generics.push(name);
431 }
432
433 pub fn get_generics(&self) -> &[String] {
435 &self.generics
436 }
437
438 pub fn clear_generics(&mut self) {
440 self.generics.clear();
441 }
442}
443
444pub struct TypeMappingUtils;
446
447impl TypeMappingUtils {
448 pub fn is_primitive(ts_type: &Type) -> bool {
450 matches!(
451 ts_type,
452 Type::String
453 | Type::Number
454 | Type::Boolean
455 | Type::Void
456 | Type::Never
457 | Type::Any
458 | Type::Unknown
459 | Type::Null
460 | Type::Undefined
461 | Type::Object
462 | Type::Symbol
463 | Type::BigInt
464 )
465 }
466
467 pub fn is_nullable(ts_type: &Type) -> bool {
469 matches!(ts_type, Type::Null | Type::Undefined)
470 }
471
472 pub fn is_optional(_ts_type: &Type) -> bool {
474 false
476 }
477
478 pub fn get_underlying_type(ts_type: &Type) -> &Type {
480 ts_type
482 }
483
484 pub fn needs_runtime(ts_type: &Type) -> bool {
486 matches!(
487 ts_type,
488 Type::Any | Type::Unknown | Type::Object | Type::Union { .. } | Type::Intersection { .. }
489 )
490 }
491
492 pub fn generate_imports(ts_type: &Type) -> Vec<String> {
494 let mut imports = Vec::new();
495
496 match ts_type {
497 Type::Any | Type::Unknown | Type::Object => {
498 imports.push("use std::any::Any;".to_string());
499 imports.push("use std::boxed::Box;".to_string());
500 }
501 Type::Union { .. } => {
502 imports.push("use serde::{Deserialize, Serialize};".to_string());
503 }
504 Type::Intersection { .. } => {
505 imports.push("use std::ops::Add;".to_string());
506 }
507 Type::Array(_) => {
508 imports.push("use std::vec::Vec;".to_string());
509 }
510 Type::Tuple(_) => {
511 }
513 Type::Function(_) => {
514 imports.push("use std::boxed::Box;".to_string());
515 }
516 Type::Null => {
517 }
519 _ => {}
520 }
521
522 imports
523 }
524}