summaryrefslogtreecommitdiffstats
path: root/src/paths.rs
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2022-11-10 17:37:24 -0600
committerToby Vincent <tobyv13@gmail.com>2022-11-10 17:37:24 -0600
commit4cac42d2299cecdc3d6a7f6d7661137da338278b (patch)
tree4b1954cd32eb54b170616b41f0c43b46f6647722 /src/paths.rs
parentc8681e50194855a2ad36bf984866a30cfcfb8ec9 (diff)
feat: add paths module and tests
Diffstat (limited to 'src/paths.rs')
-rw-r--r--src/paths.rs113
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);
+ }
+}