From d7dc8aac7712241edea0736f626b36fa99a3d953 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 4 Dec 2021 23:31:55 +0100 Subject: [PATCH] Evaluate BDATEs again --- src/eval/command.rs | 6 ++--- src/eval/command/birthday.rs | 47 +++++++++++++++++++++++++++++++++--- src/main.rs | 4 +-- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/eval/command.rs b/src/eval/command.rs index 7bb816d..129b461 100644 --- a/src/eval/command.rs +++ b/src/eval/command.rs @@ -115,7 +115,7 @@ impl<'a> CommandState<'a> { fn eval_statement(&mut self, statement: &Statement) -> Result<()> { match statement { Statement::Date(spec) => self.eval_date(spec)?, - Statement::BDate(spec) => self.eval_bdate(spec)?, + Statement::BDate(spec) => self.eval_bdate(spec), Statement::From(date) => self.from = *date, Statement::Until(date) => self.until = *date, Statement::Except(date) => self.eval_except(*date), @@ -132,8 +132,8 @@ impl<'a> CommandState<'a> { } } - fn eval_bdate(&mut self, spec: &BirthdaySpec) -> Result<()> { - self.eval_birthday_spec(spec) + fn eval_bdate(&mut self, spec: &BirthdaySpec) { + self.eval_birthday_spec(spec); } fn eval_except(&mut self, date: NaiveDate) { diff --git a/src/eval/command/birthday.rs b/src/eval/command/birthday.rs index d90d9f1..f99202a 100644 --- a/src/eval/command/birthday.rs +++ b/src/eval/command/birthday.rs @@ -1,10 +1,51 @@ +use chrono::{Datelike, NaiveDate}; + +use crate::eval::date::Dates; use crate::files::commands::BirthdaySpec; use super::super::command::CommandState; -use super::super::Result; +use super::super::{Entry, EntryKind}; impl<'a> CommandState<'a> { - pub fn eval_birthday_spec(&mut self, spec: &BirthdaySpec) -> Result<()> { - todo!() + pub fn eval_birthday_spec(&mut self, spec: &BirthdaySpec) { + // This could be optimized by restricting the range via FROM and UNTIL, + // but I don't think that kind of optimization will be necessary any + // time soon. + for year in self.range.years() { + let mut title = self.title(); + + if spec.year_known { + let age = year - spec.date.year(); + if age < 0 { + continue; + } + title.push_str(&format!(" ({})", age)); + } + + if let Some(date) = spec.date.with_year(year) { + self.add(Entry { + kind: EntryKind::Birthday, + title, + desc: self.desc(), + source: self.source(), + root: Some(date), + dates: Some(Dates::new(date, date)), + }); + } else { + assert_eq!(spec.date.month(), 2); + assert_eq!(spec.date.day(), 29); + + let first = NaiveDate::from_ymd(year, 2, 28); + let second = NaiveDate::from_ymd(year, 3, 1); + self.add(Entry { + kind: EntryKind::Birthday, + title, + desc: self.desc(), + source: self.source(), + root: Some(first), // This doesn't matter too much + dates: Some(Dates::new(first, second)), + }); + } + } } } diff --git a/src/main.rs b/src/main.rs index 7ac3fc4..a81247d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,8 +27,8 @@ fn main() -> anyhow::Result<()> { println!("{}", files.now().format("%F %T %Z")); let range = DateRange::new( - NaiveDate::from_ymd(2021, 11, 20), - NaiveDate::from_ymd(2021, 11, 26), + NaiveDate::from_ymd(2021, 1, 1), + NaiveDate::from_ymd(2021, 12, 31), ); println!("{:#?}", files.eval(EntryMode::Relevant, range));