rsx_compiler/rs_translate/
mod.rs

1use crate::Result;
2use crate::ast::*;
3use arcstr::ArcStr;
4use std::path::Path;
5use syn::__private::quote::spanned::Spanned;
6use syn::Item;
7
8/// Translate Rust AST to TypeScript AST
9pub struct RustCompiler {
10    source_id: ArcStr,
11    target: String,
12}
13
14impl RustCompiler {
15    pub fn compile_file(source: &Path, target: &Path) -> Result<ProgramNode> {
16        let source_id = ArcStr::from(source.to_string_lossy());
17        let target = target.to_string_lossy();
18        let source = std::fs::read_to_string(source)?;
19        println!("{:?}", source);
20        Self::compile(source_id, &source, &target)
21    }
22
23    pub fn compile(source_id: ArcStr, source: &str, target: &str) -> Result<ProgramNode> {
24        let ast = syn::parse_file(source)?;
25        let mut compiler = Self {
26            source_id,
27            target: target.to_string(),
28        };
29        compiler.convert_file(&ast)
30    }
31
32    fn convert_file(&mut self, file: &syn::File) -> Result<ProgramNode> {
33        let mut statements = Vec::with_capacity(file.items.len());
34        for item in file.items.as_slice() {
35            self.convert_item(item, &mut statements)?
36        }
37        Ok(ProgramNode {
38            statements,
39            span: file.__span().into(),
40            source_id: self.source_id.clone(),
41            target: self.target.clone(),
42        })
43    }
44    fn convert_item(&mut self, item: &Item, list: &mut Vec<StatementNode>) -> Result<()> {
45        match item {
46            Item::Const(_) => {
47                todo!()
48            }
49            Item::Enum(_) => {
50                todo!()
51            }
52            Item::ExternCrate(_) => {
53                todo!()
54            }
55            Item::Fn(_) => {
56                todo!()
57            }
58            Item::ForeignMod(_) => {
59                todo!()
60            }
61            Item::Impl(_) => {
62                todo!()
63            }
64            Item::Macro(_) => {
65                todo!()
66            }
67            Item::Mod(_) => {
68                todo!()
69            }
70            Item::Static(_) => {
71                todo!()
72            }
73            Item::Struct(s) => self.convert_struct_item(s, list),
74            Item::Trait(_) => {
75                todo!()
76            }
77            Item::TraitAlias(_) => {
78                todo!()
79            }
80            Item::Type(_) => {
81                todo!()
82            }
83            Item::Union(_) => {
84                todo!()
85            }
86            Item::Use(_) => {
87                todo!()
88            }
89            Item::Verbatim(_) => {
90                todo!()
91            }
92            _ => {
93                todo!()
94            }
95        }
96    }
97    fn convert_struct_item(
98        &mut self,
99        item: &syn::ItemStruct,
100        list: &mut Vec<StatementNode>,
101    ) -> Result<()> {
102        // 生成类体内容
103        let mut class_body = String::new();
104
105        // 处理结构体字段
106        if let syn::Fields::Named(fields) = &item.fields {
107            for field in &fields.named {
108                let field_name = field.ident.as_ref().unwrap();
109                let ts_type = match &field.ty {
110                    syn::Type::Path(path) => path.path.segments.last().unwrap().ident.to_string(),
111                    _ => "any".to_string(),
112                };
113                class_body.push_str(&format!("\n    {}: {};", field_name, ts_type));
114            }
115        }
116
117        let id = self.convert_identifier(&item.ident);
118
119        // 添加到语句列表
120        list.push(StatementNode::Class(Box::new(ClassStatement {
121            export: true,
122            class_name: id,
123            class_body,
124        })));
125        Ok(())
126    }
127    
128    fn convert_identifier(&mut self, ident: &syn::Ident) -> Identifier {
129        Identifier {
130            name: ArcStr::from(ident.to_string()),
131            source_id: self.source_id.clone(),
132            span: ident.__span().into(),
133        }
134    }
135}