use std::path::PathBuf; use ignore::{Walk, WalkBuilder}; use tracing::error; use crate::project::{path::PathMatcher, ProjectItem, ProjectParser, ProjectParserGroup}; use super::Filters; pub struct SearchEntry { parsers: ProjectParserGroup, iter: Walk, } impl SearchEntry { pub fn new(path_buf: PathBuf, config: &Filters) -> Self { let mut parsers = ProjectParserGroup::new(); if config.all { parsers.push(Box::new(PathMatcher::All(path_buf.to_owned()))) } if let Some(s) = config.pattern.as_ref() { parsers.push(Box::new(PathMatcher::Pattern(s.to_owned()))); }; #[cfg(feature = "git")] if config.git { parsers.push(Box::new(crate::project::git::GitMatcher)); }; let iter = WalkBuilder::new(path_buf) .standard_filters(true) .max_depth(config.max_depth) .hidden(!config.hidden) .build(); Self { parsers, iter } } } 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()) } }