specifiing dates

This commit is contained in:
Andrei Stoica 2024-04-19 20:19:31 -04:00
parent 4e26695532
commit 5cd03b713c
3 changed files with 90 additions and 5 deletions

View File

@ -25,16 +25,15 @@ digital, automated version of that.
```bash
git clone https://github.com/andrei-stoica/rusty-tasks.git
cd rusty-task
cargo install --path .
cd rusty-task cargo install --path .
```
Alternatively, there is a binary download for AMD64 Linux machines available
on the [releases page](https://github.com/andrei-stoica/rusty-tasks/releases).
Just drop that anywhere on you PATH. I recommend adding `~/bin` to your PATH
Just drop that anywhere on your PATH. I recommend adding `~/bin` to your PATH
and dropping the executable there.
If you are not on a AMD64 Linux machine, you will need to build from source.
If you are not on an AMD64 Linux machine, you will need to build from source.
I have not tested this on other platforms, so I hesitate to provide binaries
for them.
@ -46,6 +45,7 @@ Usage: rusty-tasks [OPTIONS]
Options:
-c, --config <FILE> set config file to use
-C, --current-config show current config file
-d, --date <DATE> view a specific date's file (format: YYYY-MM-DD)
-p, --previous <PREVIOUS> view previous day's notes [default: 0]
-l, --list list closest files to date
-n, --number <NUMBER> number of files to list [default: 5]
@ -61,6 +61,12 @@ Use `rust-task -p <n>` to access a previous day's file where `<n>` is the number
of days back you want to go. If a file does not exist for that day, it will
default to the closest to that date. A value of 0 represents today's file.
Alternatively, use `--date` or `-d` to specify a date specifically. Preferably
in the format year-month-day, padding with zero is optional. However, if the
year, or, year and month are omitted they will be filled in with the current
date's year and month. For example, If the current date is `2024-2-30`, the
string `4` will resolve to `2024-2-4`, and `1-4` will resolve to `2024-1-4`.
Specify a custom config location with `-c`, otherwise, it will scan for a config
in the locations specified in the [config section](#config). If no config
exists it will create one. To see what config is being loaded you can use `-C`.

View File

@ -1,3 +1,4 @@
use chrono::{Datelike, NaiveDate};
use clap::Parser;
#[derive(Parser, Debug)]
@ -10,6 +11,9 @@ pub struct Args {
#[arg(short = 'C', long)]
pub current_config: bool,
/// view a specific date's file (YYYY-MM-DD)
#[arg(short, long)]
pub date: Option<String>,
/// view previous day's notes
#[arg(short = 'p', long, default_value_t = 0)]
pub previous: u16,
@ -27,3 +31,74 @@ pub struct Args {
#[arg(short, long, action = clap::ArgAction::Count)]
pub verbose: u8,
}
pub fn smart_parse_date(date_str: &str, cur_date: &NaiveDate) -> Option<NaiveDate> {
let full_date_fmt = "%Y-%m-%d";
if let Ok(date) = NaiveDate::parse_from_str(date_str, &full_date_fmt) {
return Some(date);
}
let parts: Vec<&str> = date_str.split('-').collect();
match parts.len() {
1 => cur_date.with_day(parts[0].parse().unwrap_or(cur_date.day())),
2 => cur_date
.with_day(parts[1].parse().unwrap_or(cur_date.day()))?
.with_month(parts[0].parse().unwrap_or(cur_date.month())),
3 => NaiveDate::from_ymd_opt(
parts[0].parse().ok()?,
parts[1].parse().ok()?,
parts[2].parse().ok()?,
),
_ => None,
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_smart_parse_date() {
let good_date = NaiveDate::from_ymd_opt(2024, 01, 03).expect("Invalid date specified");
let good_date_str = good_date.format("%Y-%m-%d").to_string();
assert_eq!(
Some(good_date),
smart_parse_date(&good_date_str, &good_date)
);
let no_padding_date_str = "2024-1-3";
assert_eq!(
Some(good_date),
smart_parse_date(no_padding_date_str, &good_date)
);
let bad_day_str = "2024-01-99";
assert_eq!(None, smart_parse_date(bad_day_str, &good_date));
let no_day_str = "2024-01";
assert_eq!(None, smart_parse_date(no_day_str, &good_date));
let bad_month_str = "2024-25-01";
assert_eq!(None, smart_parse_date(bad_month_str, &good_date));
let no_month_str = "2024-14";
assert_eq!(None, smart_parse_date(no_month_str, &good_date));
let no_year_str = "01-03";
assert_eq!(Some(good_date), smart_parse_date(no_year_str, &good_date));
let bad_month_no_year_str = "25-01";
assert_eq!(None, smart_parse_date(bad_month_no_year_str, &good_date));
let bad_day_no_year_str = "01-35";
assert_eq!(None, smart_parse_date(bad_day_no_year_str, &good_date));
let no_year_month_str = "03";
assert_eq!(
Some(good_date),
smart_parse_date(no_year_month_str, &good_date)
);
let bad_day_no_year_month_str = "35";
assert_eq!(
None,
smart_parse_date(bad_day_no_year_month_str, &good_date)
);
}
}

View File

@ -97,7 +97,11 @@ fn main() {
// get clossest files to specified date
let today = Local::now().date_naive();
let target = today - TimeDelta::try_days(args.previous.into()).unwrap();
let target = if let Some(date_str) = args.date {
cli::smart_parse_date(&date_str, &today).expect("Could not parse date")
} else {
today - TimeDelta::try_days(args.previous.into()).unwrap()
};
let closest_files = TodoFile::get_closest_files(files.collect(), target, args.number);
// list files
if args.list {