1use std::env;
2use std::num::ParseIntError;
3use std::path::{self, Path};
4use time::macros::format_description;
5
6pub fn weekday_short(date: time::Date) -> String {
7 let w = date.weekday();
8
9 // Every weekday is at least three characters long.
10 // Hence, the .get() invocation should never panic.
11 w.to_string().get(0..3).unwrap().to_string()
12}
13
14pub fn calendar_file() -> Result<path::PathBuf, env::VarError> {
15 let home = env::var("HOME")?;
16 let path = Path::new(&home);
17
18 Ok(path.join(".ncalendar").join("calendar"))
19}
20
21pub fn parse_file(input: &str) -> Result<path::PathBuf, env::VarError> {
22 if input.is_empty() {
23 calendar_file()
24 } else {
25 Ok(input.into())
26 }
27}
28
29pub fn parse_today(input: &str) -> Result<time::Date, time::error::Parse> {
30 if input == "today" {
31 Ok(time::OffsetDateTime::now_local().unwrap().date())
32 } else {
33 let fmt = format_description!("[day][month][year]");
34 time::Date::parse(input, &fmt)
35 }
36}
37
38pub fn parse_days(days: &str) -> Result<time::Duration, ParseIntError> {
39 let days = days.parse::<u32>()?;
40 Ok(time::Duration::days(days.into()))
41}
42
43////////////////////////////////////////////////////////////////////////
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48 use time::macros::date;
49
50 #[test]
51 fn today_parser() {
52 assert_eq!(parse_today("02012022"), Ok(date!(2022 - 01 - 02)));
53 assert_eq!(parse_today("12122000"), Ok(date!(2000 - 12 - 12)));
54 }
55}