Flesh out commands and DATE annotations

This commit is contained in:
Joscha 2021-11-06 23:23:48 +00:00
parent dea704065c
commit afa708960c
2 changed files with 183 additions and 55 deletions

View file

@ -1,33 +1,55 @@
# today # today
## Goal 1 ## `DATE` annotations
- Support simple dates and optional times Most commands allow or require `DATE` annotations. They are roughly structured
- Support tasks, notes and birthdays 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 DATE date [delta] [time] [-- [date] [delta] [time]] [; delta]
DONE (2021-10-27 00:50) DATE weekday [time] [-- [weekday] [delta] [time]]
DATE formula [delta] [time] [-- [delta] [time]]
TASK Another simple task ```
DONE
In all three cases, the `end` must contain at least one of the optional elements
TASK Another task, this time with date if it is present. Deltas in the `end` may represent fractional days (e. g.
DATE 2021-10-26 `+3h`) as long as they are not immediately followed by a time and the `start`
DONE 2021-10-26 (2021-10-27 00:52) 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
NOTE Maybe an appointment whole-day interval).
DATE 2021-12-07 16:00
Here are some notes regarding the appointment In the case of the `date` variant, a repetition delta can be specified following
Notes can be multiple lines long a semicolon.
Including empty lines (not even whitespace) in-between If multiple `DATE` annotations from a single command start on the same date, all
As long as the text stays indented, it's still part of it except the first are ignored.
BIRTHDAY John Doe ## Examples
DATE 1987-05-12 ```
NOTE Spielerunde
BIRTHDAY Jane Doe DATE sun 22:00 -- 24:00
DATE ?-08-22 DATE sun 22:00 -- 00:00
DONE 2021-08-22 (2021-08-22 10:23) 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
``` ```

View file

@ -1,5 +1,27 @@
use chrono::{NaiveDate, NaiveDateTime, NaiveTime}; 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)] #[derive(Debug)]
pub struct Delta { pub struct Delta {
pub years: i32, pub years: i32,
@ -11,46 +33,130 @@ pub struct Delta {
} }
#[derive(Debug)] #[derive(Debug)]
struct DateDelta { struct DateEndSpec {
years: i32,
months: i32,
weeks: i32,
days: i32,
}
#[derive(Debug)]
struct TimeDelta {
hours: i32,
minutes: i32,
}
#[derive(Debug)]
struct EndDateSpec {
end: Option<NaiveDate>, end: Option<NaiveDate>,
delta: Option<Delta>, delta: Option<Delta>,
end_time: Option<NaiveTime>,
} }
#[derive(Debug)] #[derive(Debug)]
struct DateSpec { struct DateSpec {
start: NaiveDate, start: NaiveDate,
delta: Option<Delta>,
start_time: Option<NaiveTime>, start_time: Option<NaiveTime>,
offset: Option<Delta>, end: Option<DateEndSpec>,
end: Option<EndDateSpec>,
repeat: Option<Delta>, repeat: Option<Delta>,
} }
// #[derive(Debug)] #[derive(Debug)]
// struct FormulaSpec { struct WeekdayEndSpec {
// start: (), // TODO Formula end: Option<Weekday>,
// start_time: Option<NaiveTime>, delta: Option<Delta>,
// offset: Option<Delta>, end_time: Option<NaiveTime>,
// end: Option<Delta>, }
// }
#[derive(Debug)]
struct WeekdaySpec {
start: Weekday,
start_time: Option<NaiveTime>,
end: Option<WeekdayEndSpec>,
}
#[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<IntVar>),
Neg(Box<IntExpr>),
Add(Box<IntExpr>, Box<IntExpr>),
Sub(Box<IntExpr>, Box<IntExpr>),
Mul(Box<IntExpr>, Box<IntExpr>),
Div(Box<IntExpr>, Box<IntExpr>),
Mod(Box<IntExpr>, Box<IntExpr>),
Ternary(Box<BoolExpr>, Box<IntExpr>, Box<IntExpr>),
}
#[derive(Debug)]
enum BoolVar {
IsWeekday,
IsWeekend,
IsLeapYear,
}
#[derive(Debug)]
enum BoolExpr {
Lit(bool),
Var(BoolVar),
Paren(Box<BoolVar>),
Eq(Box<IntExpr>, Box<IntExpr>),
Neq(Box<IntExpr>, Box<IntExpr>),
Lt(Box<IntExpr>, Box<IntExpr>),
Lte(Box<IntExpr>, Box<IntExpr>),
Gt(Box<IntExpr>, Box<IntExpr>),
Gte(Box<IntExpr>, Box<IntExpr>),
Not(Box<BoolExpr>),
And(Box<BoolExpr>, Box<BoolExpr>),
Or(Box<BoolExpr>, Box<BoolExpr>),
Xor(Box<BoolExpr>, Box<BoolExpr>),
BEq(Box<BoolExpr>, Box<BoolExpr>),
BNeq(Box<BoolExpr>, Box<BoolExpr>),
}
#[derive(Debug)]
struct FormulaSpec {
start: Option<BoolExpr>, // None: *
start_time: Option<NaiveTime>,
offset: Option<Delta>,
end: Option<Delta>,
}
#[derive(Debug)] #[derive(Debug)]
enum Spec { enum Spec {
Date(DateSpec), Date(DateSpec),
// Formula(FormulaSpec), Weekday(WeekdaySpec),
Formula(FormulaSpec),
} }
#[derive(Debug)] #[derive(Debug)]
@ -62,15 +168,15 @@ struct Done {
#[derive(Debug)] #[derive(Debug)]
struct Task { struct Task {
title: String, title: String,
when: Option<Spec>, when: Vec<Spec>,
done: Vec<Done>,
desc: Option<String>, desc: Option<String>,
dones: Vec<Done>,
} }
#[derive(Debug)] #[derive(Debug)]
struct Note { struct Note {
title: String, title: String,
when: Spec, when: Vec<Spec>, // Not empty
desc: Option<String>, desc: Option<String>,
} }