aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock72
-rw-r--r--Cargo.toml1
-rw-r--r--src/cli.rs4
-rw-r--r--src/config.rs56
-rw-r--r--src/search.rs28
-rw-r--r--src/search/entry.rs17
-rw-r--r--src/search/entry/config.rs84
7 files changed, 143 insertions, 119 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 97198bc..fdafc74 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -324,6 +324,7 @@ dependencies = [
"iana-time-zone",
"num-integer",
"num-traits",
+ "serde",
"winapi",
]
@@ -599,6 +600,41 @@ dependencies = [
]
[[package]]
+name = "darling"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim 0.10.0",
+ "syn",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "dashmap"
version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1583,6 +1619,12 @@ dependencies = [
]
[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
name = "idna"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1647,6 +1689,7 @@ checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg",
"hashbrown",
+ "serde",
]
[[package]]
@@ -2398,6 +2441,7 @@ dependencies = [
"onefetch",
"pretty_assertions",
"serde",
+ "serde_with",
"sled",
"ssh_cfg",
"tempfile",
@@ -2651,6 +2695,34 @@ dependencies = [
]
[[package]]
+name = "serde_with"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25bf4a5a814902cd1014dbccfa4d4560fb8432c779471e96e035602519f82eef"
+dependencies = [
+ "base64",
+ "chrono",
+ "hex",
+ "indexmap",
+ "serde",
+ "serde_json",
+ "serde_with_macros",
+ "time",
+]
+
+[[package]]
+name = "serde_with_macros"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3452b4c0f6c1e357f73fdb87cd1efabaa12acf328c7a528e252893baeb3f4aa"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "serde_yaml"
version = "0.9.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index f77632f..f6a8df5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,6 +19,7 @@ ignore = "0.4.18"
onefetch = { version = "2.14.2", optional = true }
pretty_assertions = "1.3.0"
serde = { version = "1.0.147", features = ["derive"] }
+serde_with = "2.1.0"
sled = "0.34.7"
ssh_cfg = { version = "0.3.0", optional = true }
thiserror = "1.0.37"
diff --git a/src/cli.rs b/src/cli.rs
index a5cd2dd..b1af9f6 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use tracing::{metadata::LevelFilter, Level};
-use crate::{search, Config};
+use crate::{config::Entry, Config};
/// Tool for listing project directories.
#[derive(Debug, Clone, Default, Parser, Serialize, Deserialize)]
@@ -64,7 +64,7 @@ impl From<Projects> for Config {
.paths
.iter()
.cloned()
- .map(|path_buf| search::entry::Config {
+ .map(|path_buf| Entry {
path_buf,
hidden: value.hidden,
max_depth: value.max_depth,
diff --git a/src/config.rs b/src/config.rs
index 126b939..e73b7e1 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,11 +1,12 @@
use figment::{providers::Serialized, value, Figment, Metadata, Profile, Provider};
use serde::{Deserialize, Serialize};
+use std::{convert::Infallible, path::PathBuf, str::FromStr};
-use crate::search;
-
+#[serde_with::serde_as]
#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
pub struct Config {
- pub(crate) paths: Vec<search::entry::Config>,
+ #[serde_as(as = "Vec<serde_with::PickFirst<(_, serde_with::DisplayFromStr)>>")]
+ pub(crate) paths: Vec<Entry>,
}
impl Config {
@@ -30,6 +31,43 @@ impl Provider for Config {
}
}
+#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
+#[serde(default)]
+pub struct Entry {
+ pub path_buf: PathBuf,
+ pub hidden: bool,
+ pub max_depth: Option<usize>,
+ pub pattern: Option<String>,
+ #[cfg(feature = "git")]
+ pub git: bool,
+}
+
+impl Entry {
+ pub fn new(path_buf: PathBuf) -> Self {
+ Self {
+ path_buf,
+ ..Default::default()
+ }
+ }
+}
+
+impl From<PathBuf> for Entry {
+ fn from(path_buf: PathBuf) -> Self {
+ Self::new(path_buf)
+ }
+}
+
+impl FromStr for Entry {
+ type Err = Infallible;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ s.parse().map(|path_buf| Self {
+ path_buf,
+ ..Default::default()
+ })
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -37,15 +75,15 @@ mod tests {
use pretty_assertions::assert_eq;
#[test]
- fn test_extract() {
+ fn test_extract_config() {
figment::Jail::expect_with(|jail| {
jail.create_file(
"file.toml",
r#"
paths = [
"/path/to/projects",
- { path = "/path/to/other_projects", recurse = 1, hidden = true },
- { path = "/path/to/another_project", recurse = 0 },
+ { path_buf = "/path/to/other_projects", hidden = true, max_depth = 1 },
+ { path_buf = "/path/to/another_project", max_depth = 0 }
]
"#,
)?;
@@ -58,19 +96,19 @@ mod tests {
config,
Config {
paths: Vec::from([
- search::entry::Config {
+ Entry {
path_buf: "/path/to/projects".into(),
hidden: false,
max_depth: None,
..Default::default()
},
- search::entry::Config {
+ Entry {
path_buf: "/path/to/other_projects".into(),
hidden: true,
max_depth: Some(1),
..Default::default()
},
- search::entry::Config {
+ Entry {
path_buf: "/path/to/another_project".into(),
hidden: false,
max_depth: Some(0),
diff --git a/src/search.rs b/src/search.rs
index b2db0e3..6249da4 100644
--- a/src/search.rs
+++ b/src/search.rs
@@ -1,14 +1,14 @@
use figment::Provider;
use std::vec::IntoIter;
-use self::entry::Entry;
-use crate::{project::ProjectItem, Config, Result};
+use self::entry::EntryIter;
+use crate::{config::Entry, project::ProjectItem, Config, Result};
pub mod entry;
pub struct Search {
- iter: IntoIter<entry::Config>,
- curr: Option<Entry>,
+ iter: IntoIter<Entry>,
+ curr: Option<EntryIter>,
}
impl std::fmt::Debug for Search {
@@ -32,9 +32,15 @@ impl Search {
}
}
+impl From<Config> for Search {
+ fn from(config: Config) -> Self {
+ config.paths.into()
+ }
+}
+
impl<T> From<T> for Search
where
- T: IntoIterator<IntoIter = IntoIter<entry::Config>>,
+ T: IntoIterator<IntoIter = IntoIter<Entry>>,
{
fn from(value: T) -> Self {
Self {
@@ -44,12 +50,6 @@ where
}
}
-impl From<Config> for Search {
- fn from(value: Config) -> Self {
- value.paths.into()
- }
-}
-
impl Iterator for Search {
type Item = ProjectItem;
@@ -86,17 +86,17 @@ mod tests {
let project4 = temp_dir.join("subdir/project4");
let paths = Search::from(Vec::from([
- entry::Config {
+ Entry {
path_buf: project_dir.to_owned(),
max_depth: Some(1),
..Default::default()
},
- entry::Config {
+ Entry {
path_buf: project3.to_owned(),
max_depth: Some(0),
..Default::default()
},
- entry::Config {
+ Entry {
path_buf: project4.to_owned(),
max_depth: Some(0),
..Default::default()
diff --git a/src/search/entry.rs b/src/search/entry.rs
index 6cd601c..9e58962 100644
--- a/src/search/entry.rs
+++ b/src/search/entry.rs
@@ -2,21 +2,18 @@ use ignore::{Walk, WalkBuilder};
use tracing::error;
use crate::{
+ config::Entry,
project::{path::PathMatcher, ProjectParser, ProjectParserGroup},
search::ProjectItem,
};
-pub use config::Config;
-
-mod config;
-
-pub struct Entry {
+pub struct EntryIter {
parsers: ProjectParserGroup,
iter: Walk,
}
-impl Entry {
- fn new(config: &Config) -> Self {
+impl EntryIter {
+ fn new(config: &Entry) -> Self {
let iter = WalkBuilder::new(&config.path_buf)
.standard_filters(true)
.max_depth(config.max_depth)
@@ -38,13 +35,13 @@ impl Entry {
}
}
-impl From<Config> for Entry {
- fn from(config: Config) -> Self {
+impl From<Entry> for EntryIter {
+ fn from(config: Entry) -> Self {
Self::new(&config)
}
}
-impl Iterator for Entry {
+impl Iterator for EntryIter {
type Item = ProjectItem;
fn next(&mut self) -> Option<Self::Item> {
diff --git a/src/search/entry/config.rs b/src/search/entry/config.rs
deleted file mode 100644
index 4372356..0000000
--- a/src/search/entry/config.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-use serde::{Deserialize, Deserializer, Serialize};
-use std::{convert::Infallible, path::PathBuf, str::FromStr};
-
-#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize)]
-#[serde(default)]
-pub struct Config {
- pub path_buf: PathBuf,
- pub hidden: bool,
- pub max_depth: Option<usize>,
- pub pattern: Option<String>,
-
- #[cfg(feature = "git")]
- pub git: bool,
-}
-
-impl From<PathBuf> for Config {
- fn from(path_buf: PathBuf) -> Self {
- Self {
- path_buf,
- ..Default::default()
- }
- }
-}
-
-impl Config {
- pub fn new(path_buf: PathBuf) -> Self {
- Self {
- path_buf,
- ..Default::default()
- }
- }
-}
-
-impl FromStr for Config {
- type Err = Infallible;
-
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- s.parse().map(PathBuf::into)
- }
-}
-
-// Custom deserialize impl to accept either string or struct
-impl<'de> Deserialize<'de> for Config {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>,
- {
- #[derive(Deserialize)]
- #[serde(untagged)]
- enum Variants {
- String(String),
- Struct {
- path_buf: PathBuf,
- hidden: bool,
- max_depth: Option<usize>,
- pattern: Option<String>,
-
- #[cfg(feature = "git")]
- git: bool,
- },
- }
-
- match Variants::deserialize(deserializer)? {
- Variants::String(s) => s.parse().map_err(serde::de::Error::custom),
- Variants::Struct {
- path_buf,
- hidden,
- max_depth,
- pattern,
-
- #[cfg(feature = "git")]
- git,
- } => Ok(Self {
- path_buf,
- hidden,
- max_depth,
- pattern,
-
- #[cfg(feature = "git")]
- git,
- }),
- }
- }
-}