1use anyhow::Result;
2use std::path::PathBuf;
3
4pub fn is_target_file(path: &PathBuf) -> bool {
5 if let Some(extension) = path.extension() {
6 matches!(
7 extension.to_str(),
8 Some("rs" | "ts" | "js" | "py" | "go")
9 )
10 } else {
11 false
12 }
13}
14
15pub fn process_file(file_path: &PathBuf, base_path: &PathBuf) -> Result<String> {
16 use std::fs;
17 use anyhow::Context;
18
19 let content = fs::read_to_string(file_path)
20 .with_context(|| format!("Failed to read file: {}", file_path.display()))?;
21
22 let relative_path = file_path
23 .strip_prefix(base_path)
24 .with_context(|| format!("Failed to get relative path for: {}", file_path.display()))?;
25
26 Ok(format!(
27 "## {}\n```\n{}\n```\n",
28 relative_path.display(),
29 content
30 ))
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36 use std::fs::File;
37 use std::io::Write;
38 use tempfile::TempDir;
39
40 #[test]
41 fn test_is_target_file() {
42 let test_cases = vec![
43 ("test.rs", true),
44 ("test.ts", true),
45 ("test.js", true),
46 ("test.py", true),
47 ("test.go", true),
48 ("test.txt", false),
49 ("test", false),
50 ("test.RS", false), ];
52
53 for (file_name, expected) in test_cases {
54 let path = PathBuf::from(file_name);
55 assert_eq!(is_target_file(&path), expected, "Testing {}", file_name);
56 }
57 }
58
59 #[test]
60 fn test_process_file() -> Result<()> {
61 let temp_dir = TempDir::new()?;
62 let base_path = temp_dir.path().to_path_buf();
63 let file_path = base_path.join("test.rs");
64
65 let test_content = "fn main() {\n println!(\"Hello\");\n}\n";
66 let mut file = File::create(&file_path)?;
67 file.write_all(test_content.as_bytes())?;
68
69 let result = process_file(&file_path, &base_path)?;
70 let expected = format!("// test.rs\n{}\n", test_content);
71
72 assert_eq!(result, expected);
73 Ok(())
74 }
75
76 #[test]
77 fn test_process_file_not_found() {
78 let base_path = PathBuf::from(".");
79 let file_path = PathBuf::from("nonexistent.rs");
80
81 assert!(process_file(&file_path, &base_path).is_err());
82 }
83}