From 6f244a52ff249041b2331d0cde7b994d1708fc79 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 19 Dec 2017 18:20:21 +0100 Subject: [PATCH 1/2] Add function to instantiate with a given date Use that function in the `create_instance()` function which was renamed to `create_instance_today()`. --- lib/domain/libimaghabit/src/habit.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/domain/libimaghabit/src/habit.rs b/lib/domain/libimaghabit/src/habit.rs index 9a8196a5..db0f4a5d 100644 --- a/lib/domain/libimaghabit/src/habit.rs +++ b/lib/domain/libimaghabit/src/habit.rs @@ -51,8 +51,14 @@ pub trait HabitTemplate : Sized { /// By default creates an instance with the name of the template, the current time and the /// current date and copies the comment from the template to the instance. /// - /// It uses `Store::retrieve()` underneath - fn create_instance<'a>(&self, store: &'a Store) -> Result>; + /// It uses `Store::retrieve()` underneath. So if there is already an instance for the day + /// passed, this will simply return the instance. + fn create_instance_with_date<'a>(&self, store: &'a Store, date: &NaiveDate) + -> Result>; + + /// Shortcut for calling `Self::create_instance_with_date()` with an instance of + /// `::chrono::Local::today().naive_local()`. + fn create_instance_today<'a>(&self, store: &'a Store) -> Result>; /// Get instances for this template fn linked_instances(&self) -> Result; @@ -74,10 +80,10 @@ pub trait HabitTemplate : Sized { impl HabitTemplate for Entry { - fn create_instance<'a>(&self, store: &'a Store) -> Result> { + fn create_instance_with_date<'a>(&self, store: &'a Store, date: &NaiveDate) -> Result> { let name = self.habit_name()?; let comment = self.habit_comment()?; - let date = date_to_string(&Local::today().naive_local()); + let date = date_to_string(date); let id = instance_id_for_name_and_datestr(&name, &date)?; store.retrieve(id) @@ -85,14 +91,18 @@ impl HabitTemplate for Entry { .and_then(|mut entry| { { let mut hdr = entry.get_header_mut(); - try!(hdr.insert("habit.instance.name", Value::String(name))); - try!(hdr.insert("habit.instance.date", Value::String(date))); - try!(hdr.insert("habit.instance.comment", Value::String(comment))); + hdr.insert("habit.instance.name", Value::String(name))?; + hdr.insert("habit.instance.date", Value::String(date))?; + hdr.insert("habit.instance.comment", Value::String(comment))?; } Ok(entry) }) } + fn create_instance_today<'a>(&self, store: &'a Store) -> Result> { + self.create_instance_with_date(store, &Local::today().naive_local()) + } + fn linked_instances(&self) -> Result { let iter = self .get_internal_links()? From ddf703eaa0343368b0b6e5ae41d66f5f4f7f1b0d Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 19 Dec 2017 19:09:15 +0100 Subject: [PATCH 2/2] Add HabitTemplate::next_instance_date_after() Rewrite HabitTemplate::next_instance_date() to use the new function --- lib/domain/libimaghabit/src/habit.rs | 30 +++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/domain/libimaghabit/src/habit.rs b/lib/domain/libimaghabit/src/habit.rs index db0f4a5d..867f04cf 100644 --- a/lib/domain/libimaghabit/src/habit.rs +++ b/lib/domain/libimaghabit/src/habit.rs @@ -63,6 +63,9 @@ pub trait HabitTemplate : Sized { /// Get instances for this template fn linked_instances(&self) -> Result; + /// Get the date of the next date when the habit should be done + fn next_instance_date_after(&self, base: &NaiveDateTime) -> Result; + /// Get the date of the next date when the habit should be done fn next_instance_date(&self) -> Result; @@ -113,8 +116,7 @@ impl HabitTemplate for Entry { Ok(HabitInstanceStoreIdIterator::new(sidi)) } - /// Get the date of the next date when the habit should be done - fn next_instance_date(&self) -> Result { + fn next_instance_date_after(&self, base: &NaiveDateTime) -> Result { use kairos::timetype::TimeType; use kairos::parser::parse; use kairos::parser::Parsed; @@ -129,22 +131,21 @@ impl HabitTemplate for Entry { } }; - let today = TimeType::today(); - let today = today.get_moment().unwrap(); // we know this is safe. - debug!("Today is {:?}", today); + debug!("Base is {:?}", base); let basedate = date_from_s(self.habit_basedate()?)?; - debug!("Basedate is {:?}", today); + debug!("Basedate is {:?}", basedate); let increment = date_from_s(self.habit_recur_spec()?)?; - debug!("Increment is {:?}", today); + debug!("Increment is {:?}", increment); for element in basedate.every(increment)? { debug!("Calculating: {:?}", element); let element = element?.calculate()?; + debug!(" = {:?}", element); if let Some(ndt) = element.get_moment() { - if ndt > today { - debug!("-> {:?} > {:?}", ndt, today); + if ndt >= base { + debug!("-> {:?} >= {:?}", ndt, base); return Ok(ndt.date()) } } else { @@ -155,6 +156,17 @@ impl HabitTemplate for Entry { unreachable!() // until we have habit-end-date support } + /// Get the date of the next date when the habit should be done + fn next_instance_date(&self) -> Result { + use kairos::timetype::TimeType; + + let today = TimeType::today(); + let today = today.get_moment().unwrap(); // we know this is safe. + debug!("Today is {:?}", today); + + self.next_instance_date_after(&today.date().and_hms(0, 0, 0)) + } + /// Check whether the instance is a habit by checking its headers for the habit data fn is_habit_template(&self) -> Result { [