use glob::Pattern;
use std::fs;
use std::path::{Path, PathBuf};
const MODULES_PATH: &str = "src/modules";
const OUTPUT_FILE: &str = "src/entities.ts";
pub fn generate_entities_file() -> Result<(), Box<dyn std::error::Error>> {
let base_dir = std::env::current_dir()?;
let modules_path = base_dir.join(MODULES_PATH);
let output_file = base_dir.join(OUTPUT_FILE);
if !modules_path.exists() {
return Err("src/modules directory not found".into());
}
let entity_files = find_entity_files(&modules_path)?;
if entity_files.is_empty() {
println!("No entity files found");
return Ok(());
}
let mut imports = Vec::new();
let mut exports = Vec::new();
for (index, file) in entity_files.iter().enumerate() {
let relative_path = file
.strip_prefix(&base_dir)
.unwrap_or(file)
.to_string_lossy()
.replace('\\', "/");
let module_name = format!("entity_{}", index);
imports.push(format!("mod {};", module_name));
exports.push(format!(" // {}", relative_path));
}
let file_content = format!(
"// 自动生成的文件,请勿手动修改\n\
// 注意:Rust 版本的实体导出方式与 TypeScript 不同\n\
// 请根据实际情况调整导出语句\n\
{}\n\
\n\
// 导出所有实体\n\
// pub use entity_0::*;\n\
// pub use entity_1::*;\n\
// ...\n",
imports.join("\n")
);
if let Some(parent) = output_file.parent() {
fs::create_dir_all(parent)?;
}
fs::write(&output_file, file_content)?;
println!(
"Entities file generated successfully: {}",
output_file.display()
);
Ok(())
}
pub fn clear_entities_file() -> Result<(), Box<dyn std::error::Error>> {
let base_dir = std::env::current_dir()?;
let output_file = base_dir.join(OUTPUT_FILE);
let empty_content = "// 自动生成的文件,请勿手动修改\n\
// Rust 版本的实体导出方式与 TypeScript 不同\n\
// 请根据实际情况调整导出语句\n";
if let Some(parent) = output_file.parent() {
fs::create_dir_all(parent)?;
}
fs::write(&output_file, empty_content)?;
println!(
"Entities file cleared successfully: {}",
output_file.display()
);
Ok(())
}
fn find_entity_files(base_dir: &Path) -> Result<Vec<PathBuf>, Box<dyn std::error::Error>> {
let mut entity_files = Vec::new();
let pattern = Pattern::new("**/entity/**/*.rs")?;
if base_dir.is_dir() {
find_entity_files_recursive(base_dir, base_dir, &pattern, &mut entity_files)?;
}
Ok(entity_files)
}
fn find_entity_files_recursive(
base: &Path,
dir: &Path,
pattern: &Pattern,
files: &mut Vec<PathBuf>,
) -> Result<(), Box<dyn std::error::Error>> {
if dir.is_dir() {
for entry in fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
let relative_path = path.strip_prefix(base).unwrap_or(&path);
if path.is_dir() {
find_entity_files_recursive(base, &path, pattern, files)?;
} else if path.is_file() {
let path_str = relative_path.to_string_lossy().replace('\\', "/");
if pattern.matches(&path_str) {
files.push(path.to_path_buf());
}
}
}
}
Ok(())
}