use ignore::{overrides::OverrideBuilder, WalkBuilder, WalkState};
use std::{
fs::File,
path::{Path, PathBuf},
sync::{
atomic::{AtomicUsize, Ordering},
Arc,
},
};
pub fn walk<T: 'static + Clone + Send + FnMut(&Path, File)>(
paths: &[PathBuf],
callback: T,
) -> usize {
let files_scanned = Arc::new(AtomicUsize::new(0));
for path in paths {
WalkBuilder::new(path)
.hidden(false)
.require_git(false)
.overrides(
OverrideBuilder::new("")
.add("!.git/")
.unwrap() .add("!.hg/")
.unwrap() .build()
.unwrap(),
)
.build_parallel()
.run(|| {
let mut callback = callback.clone();
let files_scanned = files_scanned.clone();
Box::new(move |result| {
if let Ok(dir_entry) = result {
if dir_entry.file_type().unwrap().is_file() {
let possible_file = File::open(dir_entry.path());
if let Ok(file) = possible_file {
callback(dir_entry.path(), file);
files_scanned.fetch_add(1, Ordering::SeqCst);
}
}
}
WalkState::Continue
})
});
}
files_scanned.load(Ordering::SeqCst)
}