Skip to main content

rohas_codegen/
generator.rs

1use crate::error::Result;
2use crate::{config, python, rust, typescript, Language};
3use rohas_parser::Schema;
4use std::fs;
5use std::path::Path;
6use tracing::{debug, info};
7
8pub struct Generator {
9    language: Language,
10}
11
12impl Generator {
13    pub fn new(language: Language) -> Self {
14        Self { language }
15    }
16
17    pub fn generate(&self, schema: &Schema, output_dir: &Path) -> Result<()> {
18        info!(
19            "Generating code for {:?} in {}",
20            self.language,
21            output_dir.display()
22        );
23
24        self.create_directory_structure(output_dir)?;
25
26        self.generate_common_configs(schema, output_dir)?;
27
28        match self.language {
29            Language::TypeScript => self.generate_typescript(schema, output_dir)?,
30            Language::Python => self.generate_python(schema, output_dir)?,
31            Language::Rust => self.generate_rust(schema, output_dir)?,
32        }
33
34        info!("Code generation completed successfully");
35        Ok(())
36    }
37
38    fn create_directory_structure(&self, output_dir: &Path) -> Result<()> {
39        let dirs = [
40            "generated",
41            "generated/models",
42            "generated/dto",
43            "generated/api",
44            "generated/events",
45            "generated/cron",
46            "generated/websockets",
47            "handlers",
48            "handlers/api",
49            "handlers/events",
50            "handlers/cron",
51            "handlers/websockets",
52            "middlewares",
53        ];
54
55        for dir in &dirs {
56            let path = output_dir.join(dir);
57            if !path.exists() {
58                fs::create_dir_all(&path)?;
59                debug!("Created directory: {}", path.display());
60            }
61        }
62
63        Ok(())
64    }
65
66    fn generate_common_configs(&self, schema: &Schema, output_dir: &Path) -> Result<()> {
67        info!("Generating common configuration files");
68        config::generate_gitignore(schema, output_dir)?;
69        config::generate_editorconfig(schema, output_dir)?;
70        config::generate_readme(schema, output_dir)?;
71        Ok(())
72    }
73
74    fn generate_typescript(&self, schema: &Schema, output_dir: &Path) -> Result<()> {
75        typescript::generate_state(output_dir)?;
76        typescript::generate_models(schema, output_dir)?;
77        typescript::generate_dtos(schema, output_dir)?;
78        typescript::generate_apis(schema, output_dir)?;
79        typescript::generate_events(schema, output_dir)?;
80        typescript::generate_crons(schema, output_dir)?;
81        typescript::generate_websockets(schema, output_dir)?;
82        typescript::generate_middlewares(schema, output_dir)?;
83        typescript::generate_index(schema, output_dir)?;
84
85        info!("Generating TypeScript configuration files");
86        config::generate_package_json(schema, output_dir)?;
87        config::generate_tsconfig_json(schema, output_dir)?;
88        config::generate_rspack_config(schema, output_dir)?;
89        config::generate_nvmrc(schema, output_dir)?;
90        config::generate_prettierrc(schema, output_dir)?;
91        config::generate_prettierignore(schema, output_dir)?;
92
93        Ok(())
94    }
95
96    fn generate_python(&self, schema: &Schema, output_dir: &Path) -> Result<()> {
97        python::generate_state(output_dir)?;
98        python::generate_models(schema, output_dir)?;
99        python::generate_dtos(schema, output_dir)?;
100        python::generate_apis(schema, output_dir)?;
101        python::generate_events(schema, output_dir)?;
102        python::generate_crons(schema, output_dir)?;
103        python::generate_websockets(schema, output_dir)?;
104        python::generate_middlewares(schema, output_dir)?;
105        python::generate_init(schema, output_dir)?;
106
107        info!("Generating Python configuration files");
108        config::generate_requirements_txt(schema, output_dir)?;
109        config::generate_pyproject_toml(schema, output_dir)?;
110
111        Ok(())
112    }
113
114    fn generate_rust(&self, schema: &Schema, output_dir: &Path) -> Result<()> {
115        rust::generate_state(output_dir)?;
116        rust::generate_models(schema, output_dir)?;
117        rust::generate_dtos(schema, output_dir)?;
118        rust::generate_apis(schema, output_dir)?;
119        rust::generate_events(schema, output_dir)?;
120        rust::generate_crons(schema, output_dir)?;
121        rust::generate_websockets(schema, output_dir)?;
122        rust::generate_middlewares(schema, output_dir)?;
123        rust::generate_lib_rs(schema, output_dir)?;
124
125        info!("Generating Rust configuration files");
126        config::generate_cargo_toml(schema, output_dir)?;
127        
128        if rust::is_in_rohas_workspace(output_dir) {
129            rust::generate_dev_scripts(output_dir)?;
130        }
131
132        Ok(())
133    }
134}