diff options
author | Toby Vincent <tobyv13@gmail.com> | 2022-11-10 17:37:24 -0600 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2022-11-10 17:37:24 -0600 |
commit | 4cac42d2299cecdc3d6a7f6d7661137da338278b (patch) | |
tree | 4b1954cd32eb54b170616b41f0c43b46f6647722 /src/paths.rs | |
parent | c8681e50194855a2ad36bf984866a30cfcfb8ec9 (diff) |
feat: add paths module and tests
Diffstat (limited to 'src/paths.rs')
-rw-r--r-- | src/paths.rs | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/src/paths.rs b/src/paths.rs new file mode 100644 index 0000000..de6a2dd --- /dev/null +++ b/src/paths.rs @@ -0,0 +1,113 @@ +use ignore::{Walk, WalkBuilder}; +use std::{path::PathBuf, vec::IntoIter}; +use tracing::warn; + +pub use config::{Config, PathEntry}; +pub use error::Error; + +mod config; +mod error; + +#[derive(Default)] +pub struct Paths { + path_entries: Vec<PathEntry>, + paths_iter: Option<IntoIter<PathEntry>>, + iter: Option<Walk>, +} + +impl Paths { + pub fn new(path_entries: Vec<PathEntry>) -> Self { + Self { + path_entries, + ..Default::default() + } + } +} + +impl From<&Config> for Paths { + fn from(value: &Config) -> Self { + Paths { + path_entries: value.paths.to_owned(), + ..Default::default() + } + } +} + +impl Iterator for Paths { + type Item = PathBuf; + + fn next(&mut self) -> Option<Self::Item> { + loop { + match self.iter.as_mut().and_then(|iter| iter.next()) { + Some(Ok(d)) => return Some(d.into_path()), + Some(Err(err)) => warn!("{:?}", err), + None => match self.paths_iter.as_mut() { + Some(paths_iter) => { + let next = paths_iter.next()?; + self.iter = Some( + WalkBuilder::new(next.path) + .standard_filters(true) + .max_depth(next.recurse) + .hidden(next.hidden) + .build(), + ); + } + None => self.paths_iter = Some(self.path_entries.to_owned().into_iter()), + }, + }; + } + } +} + +#[cfg(test)] +mod tests { + use std::fs; + + use super::*; + + #[test] + fn test_iteration() { + let test_dir = tempfile::Builder::new() + .tempdir() + .expect("Failed to create tmp directory"); + + let test_path = test_dir.path().to_owned(); + + let mut projects = Vec::from([ + test_path.join("projects"), + test_path.join("projects/project1"), + test_path.join("projects/project2"), + test_path.join("project3"), + test_path.join("other_projects/project3"), + ]); + + projects.iter().for_each(|project| { + fs::create_dir_all(project).expect("Failed to create test project directory"); + }); + + let directories = Paths::new(Vec::from([ + PathEntry { + path: test_path.join("projects"), + hidden: false, + recurse: Some(1), + }, + PathEntry { + path: test_path.join("project3"), + hidden: false, + recurse: Some(0), + }, + PathEntry { + path: test_path.join("other_projects/project3"), + hidden: false, + recurse: Some(0), + }, + ])); + + let mut actual = directories.into_iter().collect::<Vec<PathBuf>>(); + + projects.sort(); + actual.sort(); + + assert_eq!(projects, actual); + } +} |