diff options
author | Toby Vincent <tobyv13@gmail.com> | 2023-05-04 19:43:08 -0500 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2023-05-04 19:43:08 -0500 |
commit | 5da4fb25f9bb72771c7f2798daa6339be0bc3900 (patch) | |
tree | c30639c7a95e1d94baff498d247eed43fdb3728e /src/search.rs | |
parent | 589cd987217755e1da7acbc304c373a75a9f7db5 (diff) |
refactor: join iterators into a single walk
Diffstat (limited to 'src/search.rs')
-rw-r--r-- | src/search.rs | 101 |
1 files changed, 50 insertions, 51 deletions
diff --git a/src/search.rs b/src/search.rs index 81049e9..27495b0 100644 --- a/src/search.rs +++ b/src/search.rs @@ -1,69 +1,68 @@ -use std::path::PathBuf; +use std::{ + ops::{Deref, DerefMut}, + path::{Path, PathBuf}, +}; -use crate::{config::Filters, project::Project, Config}; +use ignore::{DirEntry, WalkBuilder}; +use tracing::{debug, error}; -use self::entry::SearchPath; +use crate::{parser::Parser, project::Project}; -pub mod entry; - -type EntryIter = std::vec::IntoIter<PathBuf>; - -#[derive(Debug, Default, Clone)] -pub struct Search { - pub paths: Vec<PathBuf>, - pub add: Vec<PathBuf>, - pub filters: Filters, +pub struct SearchBuilder { + walk_builder: WalkBuilder, + projects: Vec<PathBuf>, + parsers: Vec<Box<dyn Parser>>, } -impl Search { - pub fn new( - Config { - paths, - add, - filters, - verbosity: _, - }: Config, - ) -> Self { +impl SearchBuilder { + pub fn new<P: AsRef<Path>>(path: P) -> Self { Self { - paths, - add, - filters, + walk_builder: WalkBuilder::new(&path), + projects: Default::default(), + parsers: Default::default(), } } -} -impl IntoIterator for Search { - type Item = Project; + pub fn project<P: AsRef<Path>>(&mut self, path: P) { + self.projects.push(path.as_ref().to_path_buf()) + } - type IntoIter = SearchIter; + pub fn parser(&mut self, parser: impl Parser + 'static) { + self.parsers.push(Box::new(parser)) + } - fn into_iter(self) -> Self::IntoIter { - SearchIter { - iter: self.paths.into_iter(), - config: self.filters, - curr: None, - } + pub fn build(mut self) -> impl Iterator<Item = Project> { + self.walk_builder + .standard_filters(true) + .build() + .inspect(|res| { + if let Err(err) = res { + error!(%err, "Ignoring errored path"); + } + }) + .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"); + } + }) + .flatten() } } -#[derive(Debug)] -pub struct SearchIter { - iter: EntryIter, - config: Filters, - curr: Option<SearchPath>, -} +impl Deref for SearchBuilder { + type Target = WalkBuilder; -impl Iterator for SearchIter { - type Item = Project; + fn deref(&self) -> &Self::Target { + &self.walk_builder + } +} - #[tracing::instrument] - fn next(&mut self) -> Option<Self::Item> { - match self.curr.as_mut().and_then(|c| c.next()) { - Some(proj) => Some(proj), - None => { - self.curr = Some(SearchPath::new(self.iter.next()?, &self.config)); - self.next() - } - } +impl DerefMut for SearchBuilder { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.walk_builder } } |