TypeScript_Rust_Compiler/
types.rs

1//! Type mapping from TypeScript to Rust
2
3use crate::ast::*;
4use crate::error::Result;
5use std::collections::HashMap;
6
7/// Type mapper for converting TypeScript types to Rust types
8pub struct TypeMapper {
9    /// Mapping of TypeScript types to Rust types
10    type_mappings: HashMap<String, String>,
11    /// Generic type parameters
12    generics: Vec<String>,
13    /// Runtime support enabled
14    runtime: bool,
15}
16
17impl TypeMapper {
18    /// Create a new type mapper
19    pub fn new(runtime: bool) -> Self {
20        let mut type_mappings = HashMap::new();
21
22        // Primitive type mappings
23        type_mappings.insert("string".to_string(), "String".to_string());
24        type_mappings.insert("number".to_string(), "f64".to_string());
25        type_mappings.insert("boolean".to_string(), "bool".to_string());
26        type_mappings.insert("void".to_string(), "()".to_string());
27        type_mappings.insert("never".to_string(), "!".to_string());
28        type_mappings.insert("any".to_string(), "Box<dyn Any>".to_string());
29        type_mappings.insert("unknown".to_string(), "Box<dyn Any>".to_string());
30        type_mappings.insert("null".to_string(), "Option<()>".to_string());
31        type_mappings.insert("undefined".to_string(), "Option<()>".to_string());
32        type_mappings.insert("object".to_string(), "Box<dyn Any>".to_string());
33        type_mappings.insert("symbol".to_string(), "Symbol".to_string());
34        type_mappings.insert("bigint".to_string(), "i64".to_string());
35
36        Self {
37            type_mappings,
38            generics: Vec::new(),
39            runtime,
40        }
41    }
42
43    /// Map a TypeScript type to Rust type
44    pub fn map_type(&mut self, ts_type: &Type) -> Result<String> {
45        match ts_type {
46            // Primitive types
47            Type::String => Ok("String".to_string()),
48            Type::Number => Ok("f64".to_string()),
49            Type::Boolean => Ok("bool".to_string()),
50            Type::Any => {
51                if self.runtime {
52                    Ok("Box<dyn Any>".to_string())
53                } else {
54                    Ok("serde_json::Value".to_string())
55                }
56            }
57            Type::Void => Ok("()".to_string()),
58            Type::Never => Ok("!".to_string()),
59            Type::Unknown => {
60                if self.runtime {
61                    Ok("Box<dyn Any>".to_string())
62                } else {
63                    Ok("serde_json::Value".to_string())
64                }
65            }
66            Type::Null => Ok("Option<()>".to_string()),
67            Type::Undefined => Ok("Option<()>".to_string()),
68            Type::Object => {
69                if self.runtime {
70                    Ok("Box<dyn Any>".to_string())
71                } else {
72                    Ok("serde_json::Value".to_string())
73                }
74            }
75            Type::Symbol => Ok("Symbol".to_string()),
76            Type::BigInt => Ok("i64".to_string()),
77
78            // Named types
79            Type::Named(name) => self.map_named_type(name),
80            Type::Qualified(qualified) => self.map_qualified_type(qualified),
81
82            // Generic types
83            Type::Generic(generic) => self.map_generic_type(generic),
84            Type::GenericNamed {
85                name,
86                type_parameters,
87            } => {
88                let rust_name = self.map_named_type(name)?;
89                if type_parameters.is_empty() {
90                    Ok(rust_name)
91                } else {
92                    let param_types: Result<Vec<String>> = type_parameters
93                        .iter()
94                        .map(|param| self.map_type(&Type::Named(param.name.clone())))
95                        .collect();
96                    let param_types = param_types?;
97                    Ok(format!("{}<{}>", rust_name, param_types.join(", ")))
98                }
99            }
100            
101            // Union and intersection types
102            Type::Union { left, right } => {
103                let left_type = self.map_type(left)?;
104                let right_type = self.map_type(right)?;
105                Ok(format!("Result<{}, {}>", left_type, right_type))
106            }
107            Type::Intersection { left, right } => {
108                let left_type = self.map_type(left)?;
109                let right_type = self.map_type(right)?;
110                Ok(format!("({} & {})", left_type, right_type))
111            }
112
113
114            // Array types
115            Type::Array(element_type) => {
116                let element_rust = self.map_type(element_type)?;
117                Ok(format!("Vec<{}>", element_rust))
118            }
119
120            // Tuple types
121            Type::Tuple(types) => self.map_tuple_type(types),
122
123            // Function types
124            Type::Function(func_type) => self.map_function_type(func_type),
125
126            // Object types
127            Type::ObjectType(obj_type) => self.map_object_type(obj_type),
128
129            // Index signatures
130            Type::IndexSignature(index_sig) => self.map_index_signature(index_sig),
131
132            // Mapped types
133            Type::Mapped(mapped) => self.map_mapped_type(mapped),
134
135            // Conditional types
136            Type::Conditional(conditional) => self.map_conditional_type(conditional),
137
138            // Template literal types
139            Type::TemplateLiteral(template) => self.map_template_literal_type(template),
140
141            // Parenthesized types
142            Type::Parenthesized(inner) => self.map_type(inner),
143
144            // Type queries
145            Type::TypeQuery(query) => self.map_type_query(query),
146
147            // Import types
148            Type::Import(import) => self.map_import_type(import),
149        }
150    }
151
152    /// Map named type
153    fn map_named_type(&self, name: &str) -> Result<String> {
154        if let Some(mapped) = self.type_mappings.get(name) {
155            Ok(mapped.clone())
156        } else {
157            // Convert to PascalCase for Rust structs/traits
158            Ok(self.to_pascal_case(name))
159        }
160    }
161
162    /// Map qualified type
163    fn map_qualified_type(&mut self, qualified: &QualifiedTypeName) -> Result<String> {
164        let left = self.map_type(&qualified.left)?;
165        Ok(format!("{}::{}", left, qualified.right))
166    }
167
168    /// Map generic type
169    fn map_generic_type(&mut self, generic: &GenericType) -> Result<String> {
170        let base_type = self.map_type(&generic.type_)?;
171        let type_args: Result<Vec<String>> = generic
172            .type_arguments
173            .iter()
174            .map(|t| self.map_type(t))
175            .collect();
176        let type_args = type_args?;
177
178        if type_args.is_empty() {
179            Ok(base_type)
180        } else {
181            Ok(format!("{}<{}>", base_type, type_args.join(", ")))
182        }
183    }
184
185    /// Map union type
186    fn map_union_type(&mut self, types: &[Type]) -> Result<String> {
187        if types.is_empty() {
188            return Ok("()".to_string());
189        }
190
191        if types.len() == 1 {
192            return self.map_type(&types[0]);
193        }
194
195        // Convert union to enum
196        let mut enum_variants = Vec::new();
197        for (i, ts_type) in types.iter().enumerate() {
198            let rust_type = self.map_type(ts_type)?;
199            enum_variants.push(format!("Variant{}({})", i, rust_type));
200        }
201
202        Ok(format!(
203            "UnionType {{\n    {}\n}}",
204            enum_variants.join(",\n    ")
205        ))
206    }
207
208    /// Map intersection type
209    fn map_intersection_type(&mut self, types: &[Type]) -> Result<String> {
210        if types.is_empty() {
211            return Ok("()".to_string());
212        }
213
214        if types.len() == 1 {
215            return self.map_type(&types[0]);
216        }
217
218        // Convert intersection to trait bounds
219        let rust_types: Result<Vec<String>> = types.iter().map(|t| self.map_type(t)).collect();
220        let rust_types = rust_types?;
221
222        Ok(format!("({})", rust_types.join(" + ")))
223    }
224
225    /// Map tuple type
226    fn map_tuple_type(&mut self, types: &[Type]) -> Result<String> {
227        if types.is_empty() {
228            return Ok("()".to_string());
229        }
230
231        let rust_types: Result<Vec<String>> = types.iter().map(|t| self.map_type(t)).collect();
232        let rust_types = rust_types?;
233
234        Ok(format!("({})", rust_types.join(", ")))
235    }
236
237    /// Map function type
238    fn map_function_type(&mut self, func_type: &FunctionType) -> Result<String> {
239        let params: Result<Vec<String>> = func_type
240            .parameters
241            .iter()
242            .map(|param| {
243                let param_type = if let Some(ref t) = param.type_ {
244                    self.map_type(t)?
245                } else {
246                    "Box<dyn Any>".to_string()
247                };
248                Ok(format!("{}: {}", param.name, param_type))
249            })
250            .collect();
251        let params = params?;
252
253        let return_type = self.map_type(&func_type.return_type)?;
254
255        Ok(format!("fn({}) -> {}", params.join(", "), return_type))
256    }
257
258    /// Map object type
259    fn map_object_type(&mut self, obj_type: &ObjectType) -> Result<String> {
260        let mut struct_fields = Vec::new();
261
262        for member in &obj_type.members {
263            match member {
264                ObjectTypeMember::Property(prop) => {
265                    let field_type = if let Some(ref t) = prop.type_ {
266                        self.map_type(t)?
267                    } else {
268                        "Box<dyn Any>".to_string()
269                    };
270
271                    let field_name = if prop.optional {
272                        format!("{}: Option<{}>", prop.name, field_type)
273                    } else {
274                        format!("{}: {}", prop.name, field_type)
275                    };
276
277                    struct_fields.push(field_name);
278                }
279                ObjectTypeMember::Method(method) => {
280                    // Methods become associated functions
281                    let params: Result<Vec<String>> = method
282                        .parameters
283                        .iter()
284                        .map(|param| {
285                            let param_type = if let Some(ref t) = param.type_ {
286                                self.map_type(t)?
287                            } else {
288                                "Box<dyn Any>".to_string()
289                            };
290                            Ok(format!("{}: {}", param.name, param_type))
291                        })
292                        .collect();
293                    let params = params?;
294
295                    let return_type = if let Some(ref t) = method.return_type {
296                        self.map_type(t)?
297                    } else {
298                        "()".to_string()
299                    };
300
301                    struct_fields.push(format!(
302                        "fn {}({}) -> {}",
303                        method.name,
304                        params.join(", "),
305                        return_type
306                    ));
307                }
308                _ => {
309                    // Handle other member types as needed
310                }
311            }
312        }
313
314        Ok(format!(
315            "struct ObjectType {{\n    {}\n}}",
316            struct_fields.join(",\n    ")
317        ))
318    }
319
320    /// Map index signature
321    fn map_index_signature(&mut self, index_sig: &IndexSignature) -> Result<String> {
322        let key_type = self.map_type(
323            &index_sig
324                .parameter
325                .type_
326                .as_ref()
327                .map_or(Type::String, |v| *v.clone()),
328        )?;
329        let value_type = self.map_type(&index_sig.type_)?;
330        Ok(format!("HashMap<{}, {}>", key_type, value_type))
331    }
332
333    /// Map mapped type
334    fn map_mapped_type(&mut self, mapped: &MappedType) -> Result<String> {
335        // Convert mapped type to generic struct
336        let key_type = self.map_type(
337            &mapped
338                .type_parameter
339                .constraint
340                .as_ref()
341                .map_or(Type::String, |v| *v.clone()),
342        )?;
343        let value_type = self.map_type(&mapped.type_)?;
344        Ok(format!("HashMap<{}, {}>", key_type, value_type))
345    }
346
347    /// Map conditional type
348    fn map_conditional_type(&mut self, conditional: &ConditionalType) -> Result<String> {
349        // Convert conditional type to trait with associated type
350        let check_type = self.map_type(&conditional.check_type)?;
351        let extends_type = self.map_type(&conditional.extends_type)?;
352        let _true_type = self.map_type(&conditional.true_type)?;
353        let _false_type = self.map_type(&conditional.false_type)?;
354
355        Ok(format!(
356            "trait ConditionalType {{\n    type Output: PartialEq<{}>;\n    fn condition<{}>() -> Self::Output;\n}}",
357            extends_type, check_type
358        ))
359    }
360
361    /// Map template literal type
362    fn map_template_literal_type(&mut self, template: &TemplateLiteralType) -> Result<String> {
363        // Convert template literal type to const generic or macro
364        Ok(format!("\"{}\"", template.head))
365    }
366
367    /// Map type query
368    fn map_type_query(&mut self, _query: &TypeQuery) -> Result<String> {
369        // Convert type query to associated type
370        Ok("TypeQuery".to_string())
371    }
372
373    /// Map import type
374    fn map_import_type(&mut self, import: &ImportType) -> Result<String> {
375        let base_type = self.map_type(&import.argument)?;
376        if let Some(ref qualifier) = import.qualifier {
377            Ok(format!("{}::{}", base_type, qualifier))
378        } else {
379            Ok(base_type)
380        }
381    }
382
383    /// Convert string to PascalCase
384    fn to_pascal_case(&self, s: &str) -> String {
385        let mut result = String::new();
386        let mut capitalize = true;
387
388        for ch in s.chars() {
389            if ch == '_' || ch == '-' {
390                capitalize = true;
391            } else if capitalize {
392                result.push(ch.to_uppercase().next().unwrap_or(ch));
393                capitalize = false;
394            } else {
395                result.push(ch);
396            }
397        }
398
399        result
400    }
401
402    /// Add generic type parameter
403    pub fn add_generic(&mut self, name: String) {
404        self.generics.push(name);
405    }
406
407    /// Get all generic type parameters
408    pub fn get_generics(&self) -> &[String] {
409        &self.generics
410    }
411
412    /// Clear generic type parameters
413    pub fn clear_generics(&mut self) {
414        self.generics.clear();
415    }
416}
417
418/// Type mapping utilities
419pub struct TypeMappingUtils;
420
421impl TypeMappingUtils {
422    /// Check if a TypeScript type is primitive
423    pub fn is_primitive(ts_type: &Type) -> bool {
424        matches!(
425            ts_type,
426            Type::String
427                | Type::Number
428                | Type::Boolean
429                | Type::Void
430                | Type::Never
431                | Type::Any
432                | Type::Unknown
433                | Type::Null
434                | Type::Undefined
435                | Type::Object
436                | Type::Symbol
437                | Type::BigInt
438        )
439    }
440
441    /// Check if a TypeScript type is nullable
442    pub fn is_nullable(ts_type: &Type) -> bool {
443        matches!(ts_type, Type::Null | Type::Undefined)
444    }
445
446    /// Check if a TypeScript type is optional
447    pub fn is_optional(_ts_type: &Type) -> bool {
448        // This would need to be determined from context
449        false
450    }
451
452    /// Get the underlying type for optional types
453    pub fn get_underlying_type(ts_type: &Type) -> &Type {
454        // This would need to be implemented based on the specific type
455        ts_type
456    }
457
458    /// Check if a TypeScript type needs runtime support
459    pub fn needs_runtime(ts_type: &Type) -> bool {
460        matches!(
461            ts_type,
462            Type::Any | Type::Unknown | Type::Object | Type::Union { .. } | Type::Intersection { .. }
463        )
464    }
465
466    /// Generate Rust imports for a type
467    pub fn generate_imports(ts_type: &Type) -> Vec<String> {
468        let mut imports = Vec::new();
469
470        match ts_type {
471            Type::Any | Type::Unknown | Type::Object => {
472                imports.push("use std::any::Any;".to_string());
473                imports.push("use std::boxed::Box;".to_string());
474            }
475            Type::Union { .. } => {
476                imports.push("use serde::{Deserialize, Serialize};".to_string());
477            }
478            Type::Intersection { .. } => {
479                imports.push("use std::ops::Add;".to_string());
480            }
481            Type::Array(_) => {
482                imports.push("use std::vec::Vec;".to_string());
483            }
484            Type::Tuple(_) => {
485                // Tuples don't need special imports
486            }
487            Type::Function(_) => {
488                imports.push("use std::boxed::Box;".to_string());
489            }
490            Type::Null => {
491                // No specific import needed for Null (unit type)
492            }
493            _ => {}
494        }
495
496        imports
497    }
498}