Skip to main content

espforge_lib/compile/
mod.rs

1use anyhow::{Context, Result};
2use espforge_configuration::EspforgeConfiguration;
3use std::fs;
4use std::path::{Path, PathBuf};
5
6use crate::parse::ConfigParser;
7
8mod assets;
9mod dependencies;
10mod generators;
11
12pub fn compile_project(config_path: &Path) -> Result<()> {
13    let compiler = ProjectCompiler::new(config_path)?;
14    compiler.run()
15}
16
17struct ProjectCompiler {
18    base_dir: PathBuf,
19    model: EspforgeConfiguration,
20}
21
22impl ProjectCompiler {
23    fn new(config_path: &Path) -> Result<Self> {
24        println!("🔍 Parsing configuration...");
25        let content = fs::read_to_string(config_path).context(format!(
26            "Failed to read configuration file: {}",
27            config_path.display()
28        ))?;
29
30        let parser = ConfigParser::new();
31        let model = parser.parse(&content)?;
32
33        let base_dir = config_path
34            .parent()
35            .unwrap_or_else(|| Path::new("."))
36            .to_path_buf();
37
38        Ok(Self { base_dir, model })
39    }
40
41    fn run(&self) -> Result<()> {
42        println!("   Project: {}", self.model.get_name());
43        println!("   Chip:    {}", self.model.get_chip());
44        println!("   Runtime: {}", self.model.runtime_name());
45        println!("🔨 Generating artifacts...");
46
47        // Step 1: Scaffold
48        generators::generate_scaffold(&self.model)?;
49
50        let project_dir = self.resolve_project_dir()?;
51        let src_dir = project_dir.join("src");
52
53        // Step 2: Dependencies
54        dependencies::add_dependencies(&project_dir, &self.model, &self.base_dir)?;
55
56        // Step 3: Assets (Wokwi, Platform, User App)
57        assets::copy_wokwi_files(&self.base_dir, &project_dir)?;
58        assets::generate_wokwi_config(&self.base_dir, &project_dir, &self.model)?;
59        //assets::provision_platform_assets(&project_dir, &src_dir)?;
60        let additional_modules = assets::inject_app_code(&self.base_dir, &src_dir)?;
61
62        // Step 4: Code Generation
63        generators::generate_component_code(&src_dir, &self.model)?;
64        generators::setup_library_structure(&src_dir, &additional_modules)?;
65        generators::generate_entry_point(&src_dir, &self.model)?;
66
67        println!("✨ Rust project generated successfully!");
68        println!();
69        println!("To compile the rust project:");
70        println!("  cd {}", self.model.get_name());
71        println!("  cargo build");
72        Ok(())
73    }
74
75    fn resolve_project_dir(&self) -> Result<PathBuf> {
76        let current_dir = std::env::current_dir().context("Failed to get current directory")?;
77        Ok(current_dir.join(self.model.get_name()))
78    }
79}