use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use ignore::{DirEntry, Error, ParallelVisitor, ParallelVisitorBuilder, WalkState};
use crate::logger::{logger, Level, Log};
type FileCollector = Vec<PathBuf>;
struct ThreadCollector {
pending: FileCollector,
collector: Arc<Mutex<FileCollector>>,
}
impl Drop for ThreadCollector {
fn drop(&mut self) {
self.collector.lock().unwrap().append(&mut self.pending);
}
}
impl ParallelVisitor for ThreadCollector {
fn visit(&mut self, entry: Result<DirEntry, Error>) -> WalkState {
match entry {
Ok(entry) => {
if entry.file_type().is_some_and(|t| t.is_file()) {
self.pending.push(entry.into_path());
}
}
Err(err) => {
logger(
Log::new(Level::Error, format!("Cannot access: {}", err), None),
None,
);
}
}
WalkState::Continue
}
}
pub struct CollectorBuilder {
pub collector: Arc<Mutex<FileCollector>>,
}
impl<'s> ParallelVisitorBuilder<'s> for CollectorBuilder {
fn build(&mut self) -> Box<dyn ParallelVisitor + 's> {
Box::new(ThreadCollector {
pending: Vec::new(),
collector: self.collector.clone(),
})
}
}