use super::WatchError;
use crate::config::{EnrichmentConfig, OutputConfig};
use std::path::PathBuf;
use std::time::Duration;
#[derive(Debug, Clone)]
pub struct WatchConfig {
pub watch_dirs: Vec<PathBuf>,
pub poll_interval: Duration,
pub enrich_interval: Duration,
pub debounce: Duration,
pub output: OutputConfig,
pub enrichment: EnrichmentConfig,
pub webhook_url: Option<String>,
pub exit_on_change: bool,
pub max_snapshots: usize,
pub quiet: bool,
pub dry_run: bool,
}
pub fn parse_duration(s: &str) -> Result<Duration, WatchError> {
let s = s.trim();
if s.is_empty() {
return Err(WatchError::InvalidInterval(s.to_string()));
}
let (num_str, unit) = if let Some(stripped) = s.strip_suffix("ms") {
(stripped, "ms")
} else if s.ends_with('s') || s.ends_with('m') || s.ends_with('h') || s.ends_with('d') {
(&s[..s.len() - 1], &s[s.len() - 1..])
} else {
return Err(WatchError::InvalidInterval(s.to_string()));
};
let value: u64 = num_str
.parse()
.map_err(|_| WatchError::InvalidInterval(s.to_string()))?;
match unit {
"ms" => Ok(Duration::from_millis(value)),
"s" => Ok(Duration::from_secs(value)),
"m" => Ok(Duration::from_secs(value * 60)),
"h" => Ok(Duration::from_secs(value * 3600)),
"d" => Ok(Duration::from_secs(value * 86400)),
_ => Err(WatchError::InvalidInterval(s.to_string())),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_duration_seconds() {
assert_eq!(parse_duration("30s").unwrap(), Duration::from_secs(30));
}
#[test]
fn test_parse_duration_minutes() {
assert_eq!(parse_duration("5m").unwrap(), Duration::from_secs(300));
}
#[test]
fn test_parse_duration_hours() {
assert_eq!(parse_duration("1h").unwrap(), Duration::from_secs(3600));
}
#[test]
fn test_parse_duration_days() {
assert_eq!(parse_duration("2d").unwrap(), Duration::from_secs(172_800));
}
#[test]
fn test_parse_duration_milliseconds() {
assert_eq!(parse_duration("500ms").unwrap(), Duration::from_millis(500));
}
#[test]
fn test_parse_duration_with_whitespace() {
assert_eq!(parse_duration(" 10s ").unwrap(), Duration::from_secs(10));
}
#[test]
fn test_parse_duration_invalid_unit() {
assert!(parse_duration("10x").is_err());
}
#[test]
fn test_parse_duration_invalid_number() {
assert!(parse_duration("abcs").is_err());
}
#[test]
fn test_parse_duration_empty() {
assert!(parse_duration("").is_err());
}
#[test]
fn test_parse_duration_no_unit() {
assert!(parse_duration("100").is_err());
}
}