use crate::config::ScanConfig;
use anyhow::Result;
use ignore::WalkBuilder;
use std::path::{Path, PathBuf};
pub struct Walker<'a> {
root: &'a Path,
config: &'a ScanConfig,
}
impl<'a> Walker<'a> {
pub fn new(root: &'a Path, config: &'a ScanConfig) -> Self {
Self { root, config }
}
pub fn walk(&self) -> Result<Vec<PathBuf>> {
let mut files = Vec::new();
let mut builder = WalkBuilder::new(self.root);
builder
.hidden(true) .git_ignore(true) .git_global(true)
.git_exclude(true);
for pattern in &self.config.ignore {
builder.add_ignore(self.root.join(pattern));
}
for entry in builder.build() {
let entry = entry?;
let path = entry.path();
if !path.is_file() {
continue;
}
if let Some(ext) = path.extension() {
let ext_str = ext.to_string_lossy().to_lowercase();
if self.config.include_extensions.contains(&ext_str) {
if let Ok(relative) = path.strip_prefix(self.root) {
files.push(relative.to_path_buf());
} else {
files.push(path.to_path_buf());
}
}
}
}
Ok(files)
}
}