use ignore::{DirEntry, Walk, WalkBuilder}; use serde::{Deserialize, Deserializer, Serialize}; use std::{convert::Infallible, path::PathBuf, str::FromStr}; #[derive(Debug, PartialEq, Eq, Clone, Default, Serialize)] #[serde(default)] pub struct SearchPath { pub path: PathBuf, pub hidden: bool, pub max_depth: Option, } impl SearchPath { pub fn filter(dir_entry: &DirEntry) -> bool { dir_entry.path().join(".git").exists() } } impl From for SearchPath { fn from(path: PathBuf) -> Self { Self { path, ..Default::default() } } } impl From for Walk { fn from(value: SearchPath) -> Self { WalkBuilder::new(value.path) .standard_filters(true) .max_depth(value.max_depth) .hidden(!value.hidden) .filter_entry(SearchPath::filter) .build() } } impl FromStr for SearchPath { type Err = Infallible; fn from_str(s: &str) -> Result { s.parse().map(PathBuf::into) } } impl<'de> Deserialize<'de> for SearchPath { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { #[derive(Deserialize)] #[serde(untagged)] enum Variants { String(String), Struct { path: PathBuf, hidden: bool, recurse: Option, }, } match Variants::deserialize(deserializer)? { Variants::String(s) => s.parse().map_err(serde::de::Error::custom), Variants::Struct { path, hidden, recurse, } => Ok(Self { path, hidden, max_depth: recurse, }), } } }