Skip to main content

grapha_core/
discover.rs

1use std::path::{Path, PathBuf};
2
3use ignore::WalkBuilder;
4
5pub fn discover_files(path: &Path, extensions: &[String]) -> anyhow::Result<Vec<PathBuf>> {
6    if path.is_file() {
7        return Ok(vec![path.to_path_buf()]);
8    }
9
10    let mut files = Vec::new();
11    let walker = WalkBuilder::new(path).hidden(true).git_ignore(true).build();
12
13    for entry in walker {
14        let entry = entry?;
15        let entry_path = entry.path();
16        if entry_path.is_file()
17            && let Some(ext) = entry_path.extension().and_then(|ext| ext.to_str())
18            && extensions.iter().any(|candidate| candidate == ext)
19        {
20            files.push(entry_path.to_path_buf());
21        }
22    }
23
24    files.sort();
25    Ok(files)
26}
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31    use std::fs;
32
33    #[test]
34    fn discovers_single_file() {
35        let dir = tempfile::tempdir().unwrap();
36        let file = dir.path().join("main.rs");
37        fs::write(&file, "fn main() {}").unwrap();
38
39        let result = discover_files(&file, &["rs".to_string()]).unwrap();
40        assert_eq!(result, vec![file]);
41    }
42
43    #[test]
44    fn discovers_files_in_directory() {
45        let dir = tempfile::tempdir().unwrap();
46        fs::write(dir.path().join("a.rs"), "").unwrap();
47        fs::write(dir.path().join("b.rs"), "").unwrap();
48        fs::write(dir.path().join("c.txt"), "").unwrap();
49
50        let result = discover_files(dir.path(), &["rs".to_string()]).unwrap();
51        assert_eq!(result.len(), 2);
52        assert!(result.iter().all(|path| path.extension().unwrap() == "rs"));
53    }
54}