use std::path::PathBuf;
#[derive(Debug, Clone)]
pub enum StartTab {
Monthly(i32, u32),
Yearly(i32),
}
#[derive(Debug, Default)]
pub struct CliArgs {
pub data_dir: Option<PathBuf>,
pub start_tab: Option<StartTab>,
}
pub fn parse_cli_args() -> CliArgs {
let args: Vec<String> = std::env::args().collect();
let mut result = CliArgs::default();
let mut i = 1;
while i < args.len() {
match args[i].as_str() {
"--data-dir" if i + 1 < args.len() => {
result.data_dir = Some(PathBuf::from(&args[i + 1]));
i += 1;
}
"--month" if i + 1 < args.len() => {
if let Some((y, m)) = parse_year_month(&args[i + 1]) {
result.start_tab = Some(StartTab::Monthly(y, m));
}
i += 1;
}
"--year" if i + 1 < args.len() => {
if let Ok(y) = args[i + 1].parse::<i32>() {
result.start_tab = Some(StartTab::Yearly(y));
}
i += 1;
}
_ => {}
}
i += 1;
}
result
}
fn parse_year_month(s: &str) -> Option<(i32, u32)> {
let parts: Vec<&str> = s.split('-').collect();
if parts.len() == 2 {
let y = parts[0].parse::<i32>().ok()?;
let m = parts[1].parse::<u32>().ok()?;
if m >= 1 && m <= 12 {
return Some((y, m));
}
}
None
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_year_month_valid() {
assert_eq!(parse_year_month("2026-05"), Some((2026, 5)));
assert_eq!(parse_year_month("2024-01"), Some((2024, 1)));
assert_eq!(parse_year_month("2024-12"), Some((2024, 12)));
assert_eq!(parse_year_month("2000-06"), Some((2000, 6)));
}
#[test]
fn test_parse_year_month_invalid() {
assert_eq!(parse_year_month(""), None);
assert_eq!(parse_year_month("2026"), None);
assert_eq!(parse_year_month("2026-00"), None); assert_eq!(parse_year_month("2026-13"), None); assert_eq!(parse_year_month("abc-def"), None);
assert_eq!(parse_year_month("2026-5-extra"), None); }
#[test]
fn test_parse_year_month_edge_cases() {
assert_eq!(parse_year_month("0-1"), Some((0, 1)));
assert_eq!(parse_year_month("9999-12"), Some((9999, 12)));
assert_eq!(parse_year_month("-1-6"), None);
}
}