summaryrefslogtreecommitdiffstats
path: root/src/search.rs
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2023-05-04 19:43:08 -0500
committerToby Vincent <tobyv13@gmail.com>2023-05-04 19:43:08 -0500
commit5da4fb25f9bb72771c7f2798daa6339be0bc3900 (patch)
treec30639c7a95e1d94baff498d247eed43fdb3728e /src/search.rs
parent589cd987217755e1da7acbc304c373a75a9f7db5 (diff)
refactor: join iterators into a single walk
Diffstat (limited to 'src/search.rs')
-rw-r--r--src/search.rs101
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
}
}