1use std::fs;
2use std::path::Path;
3
4use crate::Result;
5use crate::codegen::GeneratedCode;
6
7fn generated_header(path: &str) -> &'static str {
9 if path.ends_with(".ts") || path.ends_with(".js") {
10 "// @generated — do not edit by hand.\n"
11 } else if path.ends_with(".py") || path.ends_with(".pyi") {
12 "# @generated — do not edit by hand.\n"
13 } else {
14 "// @generated — do not edit by hand.\n"
16 }
17}
18
19pub fn write_generated_code(generated_code: &GeneratedCode, output_dir: &Path) -> Result<()> {
20 fs::create_dir_all(output_dir)?;
21
22 for (relative_path, content) in &generated_code.files {
23 let file_path = output_dir.join(relative_path);
24
25 if let Some(parent) = file_path.parent() {
26 fs::create_dir_all(parent)?;
27 }
28
29 let header = generated_header(relative_path);
30 let final_content = if content.starts_with(header) {
31 content.clone()
32 } else {
33 format!("{}{}", header, content)
34 };
35
36 fs::write(&file_path, final_content)?;
37 }
38
39 tracing::info!("Successfully wrote all generated files");
40 Ok(())
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46 use std::collections::HashMap;
47 use tempfile::TempDir;
48
49 fn create_test_generated_code() -> GeneratedCode {
50 let mut files = HashMap::new();
51 files.insert(
52 "test_handler.rs".to_string(),
53 "// Test handler content\npub trait TestHandler {}\n".to_string(),
54 );
55 files.insert(
56 "test_routes.rs".to_string(),
57 "// Test routes content\npub fn test_route() {}\n".to_string(),
58 );
59
60 GeneratedCode { files }
61 }
62
63 #[test]
64 fn test_write_generated_code() {
65 let temp_dir = TempDir::new().unwrap();
66 let generated_code = create_test_generated_code();
67
68 let result = write_generated_code(&generated_code, temp_dir.path());
69 assert!(result.is_ok());
70
71 assert!(temp_dir.path().join("test_handler.rs").exists());
72 assert!(temp_dir.path().join("test_routes.rs").exists());
73 }
74}