use std::collections::BTreeMap;
use std::path::Path;
use anyhow::Result;
use ignore::WalkBuilder;
pub fn discover_files(root: &Path) -> Result<BTreeMap<std::path::PathBuf, String>> {
let mut out = BTreeMap::new();
for result in WalkBuilder::new(root)
.max_depth(Some(50))
.follow_links(true)
.build()
{
let entry = result.map_err(|e| anyhow::anyhow!("walk: {e}"))?;
let path = entry.path();
if path.extension().is_some_and(|e| e == "rs") && path.is_file() {
match std::fs::read_to_string(path) {
Ok(s) => {
out.insert(path.to_path_buf(), s);
}
Err(e) => {
eprintln!("warning: could not read {}: {e}", path.display());
}
}
}
}
Ok(out)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn discovers_rust_files_only() {
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src");
assert!(root.exists(), "src/ missing (run from repo root)");
let files = discover_files(&root).unwrap();
assert!(
files
.keys()
.any(|p| p.extension().is_some_and(|e| e == "rs")),
"expected at least one .rs file under src/, got {}",
files.len()
);
assert!(!files
.keys()
.any(|p| p.extension().is_some_and(|e| e == "toml")));
}
}