summaryrefslogtreecommitdiffstats
path: root/src/search/entry.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/search/entry.rs')
-rw-r--r--src/search/entry.rs75
1 files changed, 58 insertions, 17 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