date-utilities 0.0.4

Lightweight utilities for working with dates
Documentation
use date_utilities::{Duration, FORMATS, Instant};
use std::borrow::Cow;

fn main() {
    let mut args = std::env::args().skip(1);
    // let format = arg.as_deref().unwrap_or_default();

    let mut format = Cow::Borrowed(FORMATS::FULL_MINIMAL);
    let mut now = Instant::now_local();

    while let Some(arg) = args.next() {
        match arg.as_str() {
            "--help" => {
                println!("now *format*");
                println!("in date-utilities");
                println!("by kaleidawave");
                return;
            }
            "--format" => {
                let next = args.next().unwrap();
                format = match next.as_str() {
                    "FULL_MINIMAL" => Cow::Borrowed(FORMATS::FULL_MINIMAL),
                    "DATE_MONTH_YEAR" => Cow::Borrowed(FORMATS::DATE_MONTH_YEAR),
                    "MONTH_DATE_YEAR" => Cow::Borrowed(FORMATS::MONTH_DATE_YEAR),
                    "DATE_NAME_MONTH_YEAR" => Cow::Borrowed(FORMATS::DATE_NAME_MONTH_YEAR),
                    "TIME_DATE_NAME_MONTH_YEAR" => {
                        Cow::Borrowed(FORMATS::TIME_DATE_NAME_MONTH_YEAR)
                    }
                    "TIME" => Cow::Borrowed(FORMATS::TIME),
                    "WEEK" => Cow::Borrowed(FORMATS::WEEK),
                    "TIME_WITH_SECONDS" => Cow::Borrowed(FORMATS::TIME_WITH_SECONDS),
                    _ => Cow::Owned(next),
                };
            }
            "--add" => {
                let next = args.next().unwrap();
                let duration = duration_from_string(&next);
                now += duration;
            }
            "--sub" => {
                let next = args.next().unwrap();
                let duration = duration_from_string(&next);
                now -= duration;
            }
            arg => {
                panic!("unknown {arg:?}");
            }
        }
    }

    let formatted = now.format(&format);

    {
        use std::io::{self, IsTerminal, Write};
        let mut stdout = io::stdout().lock();
        if stdout.is_terminal() {
            writeln!(&mut stdout, "{formatted}").unwrap();
        } else {
            write!(&mut stdout, "{formatted}").unwrap();
        }
    }
}

fn duration_from_string(on: &str) -> Duration {
    fn non_alphabetic(c: char) -> bool {
        !c.is_alphabetic()
    }

    let (left, right) = on.rsplit_once(non_alphabetic).unwrap();

    let left: u64 = str::parse(left).unwrap();
    match right {
        "day" | "days" => Duration::from_days(left),
        "week" | "weeks" => Duration::from_days(left * 7),
        time => panic!("unknown duration {time}"),
    }
}