diff options
Diffstat (limited to 'src/search.rs')
-rw-r--r-- | src/search.rs | 92 |
1 files changed, 56 insertions, 36 deletions
diff --git a/src/search.rs b/src/search.rs index 27495b0..9f85f3a 100644 --- a/src/search.rs +++ b/src/search.rs @@ -3,66 +3,86 @@ use std::{ path::{Path, PathBuf}, }; -use ignore::{DirEntry, WalkBuilder}; -use tracing::{debug, error}; +use ignore::WalkBuilder; -use crate::{parser::Parser, project::Project}; - -pub struct SearchBuilder { - walk_builder: WalkBuilder, - projects: Vec<PathBuf>, - parsers: Vec<Box<dyn Parser>>, +pub struct Search { + inner: WalkBuilder, + paths: Vec<PathBuf>, } -impl SearchBuilder { +impl Search { pub fn new<P: AsRef<Path>>(path: P) -> Self { Self { - walk_builder: WalkBuilder::new(&path), - projects: Default::default(), - parsers: Default::default(), + inner: WalkBuilder::new(&path), + paths: Vec::from([path.as_ref().to_owned()]), } } - pub fn project<P: AsRef<Path>>(&mut self, path: P) { - self.projects.push(path.as_ref().to_path_buf()) - } - - pub fn parser(&mut self, parser: impl Parser + 'static) { - self.parsers.push(Box::new(parser)) + pub fn add<P: AsRef<Path>>(&mut self, path: P) { + self.paths.push(path.as_ref().to_owned()); + self.inner.add(path); } - pub fn build(mut self) -> impl Iterator<Item = Project> { - self.walk_builder + pub fn build(mut self) -> impl Iterator<Item = PathBuf> { + self.inner .standard_filters(true) .build() - .inspect(|res| { - if let Err(err) = res { - error!(%err, "Ignoring errored path"); + .flat_map(move |res| match res.map(|d| d.into_path()) { + Ok(p) if self.paths.contains(&p) => { + tracing::debug!(?p, "Ignoring search directory"); + None } - }) - .flatten() - .map(DirEntry::into_path) - .chain(self.projects.into_iter()) - .map(move |p| self.parsers.parse(p)) - .inspect(|res| { - if let Err(err) = res { - debug!(%err, "Failed to match"); + Ok(p) => Some(p), + Err(err) => { + tracing::error!(%err, "Ignoring errored path"); + None } }) - .flatten() } } -impl Deref for SearchBuilder { +impl Deref for Search { type Target = WalkBuilder; fn deref(&self) -> &Self::Target { - &self.walk_builder + &self.inner } } -impl DerefMut for SearchBuilder { +impl DerefMut for Search { fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.walk_builder + &mut self.inner + } +} + +impl IntoIterator for Search { + type Item = PathBuf; + + type IntoIter = std::vec::IntoIter<Self::Item>; + + fn into_iter(self) -> Self::IntoIter { + self.build().collect::<Vec<_>>().into_iter() + } +} + +impl TryFrom<crate::config::Search> for Search { + type Error = (); + + fn try_from(value: crate::config::Search) -> Result<Self, Self::Error> { + if value.paths.is_empty() { + return Err(()); + } + + let (init, paths) = value.paths.split_first().unwrap(); + let mut search = Search::new(init); + + for path in paths { + search.add(path); + } + + search.max_depth(value.max_depth); + search.hidden(!value.hidden); + + Ok(search) } } |