use std::path::PathBuf; use clap::Parser; use humantime::Duration; use crate::error::ParseError; #[derive(Debug, Parser, Clone)] pub struct CliArgs { /// The time to wait before refreshing repositories. /// eg. 10m, 60s, etc. #[clap(short, long, default_value = "10m")] #[arg(value_parser = parse_refresh_time)] pub refresh_time: Duration, /// The directory to search for git repositories. /// This must be valid, and accessible by the application. #[clap(required = true)] #[arg(value_parser = parse_directory)] pub directory: PathBuf, /// The limit to the depth of recursion in the directory tree. /// Keep this number reasonable. #[clap(short, long, default_value_t = 3)] pub max_recursion_depth: usize, } impl Default for CliArgs { fn default() -> Self { Self { refresh_time: parse_refresh_time("10m").unwrap(), directory: Default::default(), max_recursion_depth: 3, } } } /// Parses the given string argument into a `PathBuf` and checks if it is a valid directory. /// /// # Arguments /// /// - `arg` - A string containing the path to be parsed. /// /// # Returns /// /// This function returns `Ok(PathBuf)` if the path is a valid directory, /// or `Err(ParseError)` if the path is not a valid directory. fn parse_directory(arg: &str) -> Result { let directory = PathBuf::from(arg); if directory.exists() && directory.is_dir() { Ok(PathBuf::from(arg)) } else { Err(ParseError::new( "path does not exist or is not a directory.", )) } } /// Parses a duration string into a `humantime::Duration`. /// /// This function takes a duration string (e.g., "10m", "2h 15min") /// and parses it to `humantime::Duration`. /// /// # Arguments /// /// - `arg` - A string representing the duration. /// /// # Returns /// /// A `Result` which is `Ok(humantime::Duration)` if the string is successfully parsed, /// or `Err(ParseError)` if unsuccessful. fn parse_refresh_time(arg: &str) -> Result { arg.parse::().map_err(ParseError::from) }