espforge_lib/generate/
operations.rs1use super::manifest;
4use anyhow::{Context, Result};
5use include_dir::Dir;
6use log::{debug, info};
7use std::fs;
8use std::path::Path;
9
10pub fn copy_components(src_path: &Path) -> Result<()> {
11 let components_path = src_path.join("components");
12 copy_dir_files(
13 manifest::components_dir(),
14 &components_path,
15 |path| path.ends_with(".rs")
16 ).context("Failed to copy components")?;
17 info!("Copied component files");
18 Ok(())
19}
20
21pub fn copy_devices(src_path: &Path) -> Result<()> {
22 let devices_path = src_path.join("devices");
23 fs::create_dir_all(&devices_path)
24 .with_context(|| format!("Failed to create directory: {}", devices_path.display()))?;
25
26 let mut modules = Vec::new();
27
28 for subdir in manifest::devices_dir().dirs() {
29 let device_name = subdir.path().file_name().unwrap().to_str().unwrap();
30
31 if let Some(file) = subdir.files().find(|f| f.path().file_name().and_then(|n| n.to_str()) == Some("device.rs")) {
33 let dest_file = devices_path.join(format!("{}.rs", device_name));
35 fs::write(&dest_file, file.contents())
36 .with_context(|| format!("Failed to write device file: {}", dest_file.display()))?;
37 modules.push(device_name.to_string());
38 debug!("Copied device: {}", device_name);
39 }
40 }
41
42 modules.sort();
44
45 generate_mod_file(&devices_path, &modules, true)?;
47 info!("Copied device files");
48 Ok(())
49}
50
51pub fn copy_platform_files(src_path: &Path) -> Result<()> {
52 let platform_path = src_path.join("platform");
53 copy_dir_files(manifest::platform_dir(), &platform_path, |_| true)
54 .context("Failed to copy platform files")?;
55 info!("Copied platform files");
56 Ok(())
57}
58
59pub fn copy_dir_files<F>(dir: &Dir<'_>, dest_path: &Path, filter: F) -> Result<()>
60where
61 F: Fn(&str) -> bool,
62{
63 fs::create_dir_all(dest_path)
64 .with_context(|| format!("Failed to create directory: {}", dest_path.display()))?;
65
66 for file in dir.files() {
67 let file_path_str = file.path().to_str().context("Invalid UTF-8 in file path")?;
68
69 if filter(file_path_str) {
70 let dest_file = dest_path.join(file.path());
71 fs::write(&dest_file, file.contents())
72 .with_context(|| format!("Failed to write file: {}", dest_file.display()))?;
73 debug!("Copied: {}", file_path_str);
74 }
75 }
76
77 Ok(())
78}
79
80pub fn copy_globals_files(src_path: &Path) -> Result<()> {
81 let globals_path = src_path.join("globals");
82 copy_dir_files(
83 manifest::globals_dir(),
84 &globals_path,
85 |path| path.ends_with(".rs")
86 ).context("Failed to copy global files")?;
87 info!("Copied global files");
88 Ok(())
89}
90
91
92pub fn generate_mod_file(dir_path: &Path, modules: &[String], use_pub_use: bool) -> Result<()> {
93 let mut content = String::from("#![allow(unused_imports)]\n");
94
95 for module in modules {
96 content.push_str(&format!("pub mod {};\n", module));
97 if use_pub_use {
98 content.push_str(&format!("pub use {}::*;\n", module));
99 } else {
100 content.push_str(&format!("pub use {}::*;\n", module));
101 }
102 }
103
104 let mod_file = dir_path.join("mod.rs");
105 fs::write(&mod_file, content)
106 .with_context(|| format!("Failed to write mod file: {}", mod_file.display()))?;
107
108 debug!("Generated mod.rs with {} modules", modules.len());
109 Ok(())
110}