use ignore::{Walk, WalkBuilder}; use tracing::error; use crate::{ config::SearchEntryConfig, project::{path::PathMatcher, ProjectParser, ProjectParserGroup}, search::ProjectItem, }; pub struct SearchEntry { parsers: ProjectParserGroup, iter: Walk, } impl SearchEntry { fn new(config: &SearchEntryConfig) -> Self { let iter = WalkBuilder::new(&config.path_buf) .standard_filters(true) .max_depth(config.max_depth) .hidden(!config.hidden) .build(); let mut parsers = ProjectParserGroup::new(); if let Some(s) = config.pattern.as_ref() { parsers.push(Box::new(PathMatcher(s.to_owned()))); }; #[cfg(feature = "git")] if config.git { parsers.push(Box::new(crate::project::git::GitMatcher)); }; Self { parsers, iter } } } impl From for SearchEntry { fn from(config: SearchEntryConfig) -> Self { Self::new(&config) } } impl Iterator for SearchEntry { type Item = ProjectItem; fn next(&mut self) -> Option { match self.iter.next()? { Ok(dir_entry) => self.parsers.parse(dir_entry.into_path()), Err(err) => { error!(%err, "Ignoring errored path"); None } } .or_else(|| self.next()) } }