From afa708960cfcd1137b7314e20e7996fdcc938692 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 6 Nov 2021 23:23:48 +0000 Subject: [PATCH] Flesh out commands and DATE annotations --- README.md | 76 +++++++++++++++-------- src/commands.rs | 162 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 183 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 89680a9..f5eb038 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,55 @@ # today -## Goal 1 +## `DATE` annotations -- Support simple dates and optional times -- Support tasks, notes and birthdays +Most commands allow or require `DATE` annotations. They are roughly structured +like `DATE start [-- end]`. The `end` part can only contain time-related +information if the `start` specifies a time. +More specifically, there are three variants of the `DATE` annotation: ``` -TASK Task without date -DONE (2021-10-27 00:50) - -TASK Another simple task -DONE - -TASK Another task, this time with date -DATE 2021-10-26 -DONE 2021-10-26 (2021-10-27 00:52) - -NOTE Maybe an appointment -DATE 2021-12-07 16:00 - Here are some notes regarding the appointment - Notes can be multiple lines long - - Including empty lines (not even whitespace) in-between - As long as the text stays indented, it's still part of it - -BIRTHDAY John Doe -DATE 1987-05-12 - -BIRTHDAY Jane Doe -DATE ?-08-22 -DONE 2021-08-22 (2021-08-22 10:23) +DATE date [delta] [time] [-- [date] [delta] [time]] [; delta] +DATE weekday [time] [-- [weekday] [delta] [time]] +DATE formula [delta] [time] [-- [delta] [time]] +``` + +In all three cases, the `end` must contain at least one of the optional elements +if it is present. Deltas in the `end` may represent fractional days (e. g. +`+3h`) as long as they are not immediately followed by a time and the `start` +includes a time. Other deltas may only represent whole-day intervals (they may +contain sub-day specifiers like `+24h` or `+25h-60m` as long as they sum to a +whole-day interval). + +In the case of the `date` variant, a repetition delta can be specified following +a semicolon. + +If multiple `DATE` annotations from a single command start on the same date, all +except the first are ignored. + +## Examples +``` +NOTE Spielerunde +DATE sun 22:00 -- 24:00 +DATE sun 22:00 -- 00:00 +DATE sun 22:00 -- +2h +DATE (wd = sun) 22:00 -- 24:00 +DATE 2021-11-07 22:00 -- 24:00; +w +DATE 2021-11-07 22:00 -- +2h; +w + +NOTE daily +DATE * +DATE (true) +DATE 2021-11-07; +d + +NOTE on weekends +DATE (wd = sat | wd = sun) + +NOTE weekends +DATE sat -- sun +DATE 2021-11-06 -- 2021-11-07; +w +DATE 2021-11-06 -- +d; +w +DATE (wd = sat) -- +d + +NOTE last of each month +DATE (m = 1) -d ``` diff --git a/src/commands.rs b/src/commands.rs index bdf0398..51d6174 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -1,5 +1,27 @@ use chrono::{NaiveDate, NaiveDateTime, NaiveTime}; +#[derive(Debug)] +enum Weekday { + Monday, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, + Sunday, +} + +#[derive(Debug)] +enum DeltaStep { + Year(i32), + Month(i32), + Day(i32), + Week(i32), + Hour(i32), + Minute(i32), + Weekday(i32, Weekday), +} + #[derive(Debug)] pub struct Delta { pub years: i32, @@ -11,46 +33,130 @@ pub struct Delta { } #[derive(Debug)] -struct DateDelta { - years: i32, - months: i32, - weeks: i32, - days: i32, -} - -#[derive(Debug)] -struct TimeDelta { - hours: i32, - minutes: i32, -} - -#[derive(Debug)] -struct EndDateSpec { +struct DateEndSpec { end: Option, delta: Option, + end_time: Option, } #[derive(Debug)] struct DateSpec { start: NaiveDate, + delta: Option, start_time: Option, - offset: Option, - end: Option, + end: Option, repeat: Option, } -// #[derive(Debug)] -// struct FormulaSpec { -// start: (), // TODO Formula -// start_time: Option, -// offset: Option, -// end: Option, -// } +#[derive(Debug)] +struct WeekdayEndSpec { + end: Option, + delta: Option, + end_time: Option, +} + +#[derive(Debug)] +struct WeekdaySpec { + start: Weekday, + start_time: Option, + end: Option, +} + +#[derive(Debug)] +enum IntVar { + /// `j`, see https://en.wikipedia.org/wiki/Julian_day + JulianDay, + /// `y` + Year, + /// `yl`, length of the current year in days + YearLength, + /// `yd`, day of the year + YearDay, + /// `m` + Month, + /// `ml`, length of the current month in days + MonthLength, + /// `d`, day of the month + MonthDay, + /// `iy`, ISO 8601 year + IsoYear, + /// `iyl`, length of current ISO 8601 year **in weeks** + IsoYearLength, + /// `iw`, ISO 8601 week + IsoWeek, + /// `wd`, day of the week, starting at monday with 1 + Weekday, + /// `e`, day of the year that easter falls on + Easter, + /// `mon`, always 1 + Monday, + /// `tue`, always 2 + Tuesday, + /// `wed`, always 3 + Wednesday, + /// `thu`, always 4 + Thursday, + /// `fri`, always 5 + Friday, + /// `sat`, always 6 + Saturday, + /// `sun`, always 7 + Sunday, +} + +#[derive(Debug)] +enum IntExpr { + Lit(i64), + Var(IntVar), + Paren(Box), + Neg(Box), + Add(Box, Box), + Sub(Box, Box), + Mul(Box, Box), + Div(Box, Box), + Mod(Box, Box), + Ternary(Box, Box, Box), +} + +#[derive(Debug)] +enum BoolVar { + IsWeekday, + IsWeekend, + IsLeapYear, +} + +#[derive(Debug)] +enum BoolExpr { + Lit(bool), + Var(BoolVar), + Paren(Box), + Eq(Box, Box), + Neq(Box, Box), + Lt(Box, Box), + Lte(Box, Box), + Gt(Box, Box), + Gte(Box, Box), + Not(Box), + And(Box, Box), + Or(Box, Box), + Xor(Box, Box), + BEq(Box, Box), + BNeq(Box, Box), +} + +#[derive(Debug)] +struct FormulaSpec { + start: Option, // None: * + start_time: Option, + offset: Option, + end: Option, +} #[derive(Debug)] enum Spec { Date(DateSpec), - // Formula(FormulaSpec), + Weekday(WeekdaySpec), + Formula(FormulaSpec), } #[derive(Debug)] @@ -62,15 +168,15 @@ struct Done { #[derive(Debug)] struct Task { title: String, - when: Option, + when: Vec, + done: Vec, desc: Option, - dones: Vec, } #[derive(Debug)] struct Note { title: String, - when: Spec, + when: Vec, // Not empty desc: Option, }