diff options
Diffstat (limited to 'src/search')
-rw-r--r-- | src/search/entry.rs | 75 | ||||
-rw-r--r-- | src/search/entry/config.rs | 14 |
2 files changed, 58 insertions, 31 deletions
diff --git a/src/search/entry.rs b/src/search/entry.rs index 778c75c..1e49a67 100644 --- a/src/search/entry.rs +++ b/src/search/entry.rs @@ -1,49 +1,90 @@ -use ignore::{DirEntry, Walk}; -use tracing::error; +use ignore::{Walk, WalkBuilder}; +use tracing::{error, warn}; -use crate::project::{GitProject, PathProject, ProjectItem}; +use crate::{ + project::{path::PathMatcher, ProjectParser}, + search::ProjectItem, +}; pub use config::Config; mod config; pub struct Entry { - config: Config, + path_parser: Option<PathMatcher>, + + #[cfg(feature = "git")] + git_parser: Option<crate::project::git::GitMatcher>, + iter: Walk, } impl std::fmt::Debug for Entry { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("SearchPath") - .field("config", &self.config) - .finish() + let mut debug = f.debug_struct("Entry"); + debug.field("path_matcher", &self.path_parser); + + #[cfg(feature = "git")] + debug.field("git_matcher", &self.git_parser); + + debug.finish() } } impl Entry { - pub fn parse_dir_entry(&self, dir_entry: DirEntry) -> Option<ProjectItem> { - if self.config.git { - if let Ok(git) = GitProject::try_from(dir_entry.to_owned()) { - return Some(Box::new(git)); - }; + fn new(config: &Config) -> Self { + let iter = WalkBuilder::new(&config.path_buf) + .standard_filters(true) + .max_depth(config.max_depth) + .hidden(!config.hidden) + .build(); + + Self { + iter, + path_parser: config.pattern.as_ref().map(|s| PathMatcher(s.to_owned())), + + #[cfg(feature = "git")] + git_parser: config.git.then_some(crate::project::git::GitMatcher), + } + } +} + +impl ProjectParser for Entry { + #[tracing::instrument] + fn parse_project(&self, path_buf: std::path::PathBuf) -> Option<ProjectItem> { + #[cfg(feature = "git")] + if let Some(p) = self + .git_parser + .as_ref() + .and_then(|m| m.parse_project(path_buf.to_owned())) + { + return Some(p); }; - if let Some(pattern) = &self.config.pattern { - if let Ok(proj) = PathProject::try_from((pattern, dir_entry)) { - return Some(Box::new(proj)); - }; + if let Some(p) = self + .path_parser + .as_ref() + .and_then(|m| m.parse_project(path_buf)) + { + return Some(p); }; None } } +impl From<Config> for Entry { + fn from(config: Config) -> Self { + Self::new(&config) + } +} + impl Iterator for Entry { type Item = ProjectItem; fn next(&mut self) -> Option<Self::Item> { match self.iter.next()? { - Ok(dir_entry) => self.parse_dir_entry(dir_entry), + Ok(dir_entry) => self.parse_project(dir_entry.into_path()), Err(err) => { error!(%err, "Ignoring errored path"); None diff --git a/src/search/entry/config.rs b/src/search/entry/config.rs index d325b58..24c7971 100644 --- a/src/search/entry/config.rs +++ b/src/search/entry/config.rs @@ -1,9 +1,6 @@ -use ignore::WalkBuilder; use serde::{Deserialize, Deserializer, Serialize}; use std::{convert::Infallible, path::PathBuf, str::FromStr}; -use super::Entry; - #[derive(Debug, PartialEq, Eq, Clone, Default, Serialize)] #[serde(default)] pub struct Config { @@ -14,17 +11,6 @@ pub struct Config { pub pattern: Option<String>, } -impl From<Config> for Entry { - fn from(config: Config) -> Self { - let iter = WalkBuilder::new(&config.path_buf) - .standard_filters(true) - .max_depth(config.max_depth) - .hidden(!config.hidden) - .build(); - Self { iter, config } - } -} - impl From<PathBuf> for Config { fn from(path_buf: PathBuf) -> Self { Self { |