From 13af935178655b3ea3a8b631931a4bd68934d4af Mon Sep 17 00:00:00 2001 From: Akshay Date: Sat, 15 Feb 2020 18:20:36 +0530 Subject: rework habit structures --- src/habit.rs | 132 +++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 84 insertions(+), 48 deletions(-) diff --git a/src/habit.rs b/src/habit.rs index 6445545..cd1703e 100644 --- a/src/habit.rs +++ b/src/habit.rs @@ -3,73 +3,109 @@ use std::collections::HashMap; use chrono::NaiveDate; use serde::Serialize; +#[derive(Serialize, Debug, Clone, Copy)] +pub enum HabitType { + Bit(bool), + Count(u32), +} + +impl HabitType { + fn inner_bit(&self) -> bool { + if let HabitType::Bit(v) = self { + *v + } else { + panic!("why"); + } + } + fn inner_count(&self) -> u32 { + if let HabitType::Count(v) = self { + *v + } else { + panic!("why"); + } + } +} + +pub trait HabitTrait { + fn set_name(&mut self, name: impl AsRef); + fn set_goal(&mut self, goal: HabitType); + fn get_name(&self) -> String; + fn get_by_date(&self, date: NaiveDate) -> Option<&HabitType>; + fn insert_entry(&mut self, date: NaiveDate, val: HabitType); + fn reached_goal(&self, date: NaiveDate) -> bool; +} + #[derive(Serialize, Debug)] -pub struct Habit { +pub struct Habit { name: String, - stats: HashMap, - goal: T, + stats: HashMap, + goal: HabitType, +} + +pub enum TrackEvent { + Increment, + Decrement, } -impl Habit -where - T: Copy, -{ - pub fn new(name: &str, goal: T) -> Habit { +impl Habit { + pub fn new(name: impl AsRef, goal: HabitType) -> Self { return Habit { - name: name.to_owned(), + name: name.as_ref().to_owned(), stats: HashMap::new(), goal, }; } - pub fn get_name(&self) -> String { - return self.name.to_owned(); - } - pub fn get_by_date(&self, date: NaiveDate) -> Option<&T> { - self.stats.get(&date) - } - pub fn insert_entry(&mut self, date: NaiveDate, val: T) { - *self.stats.entry(date).or_insert(val) = val; - } -} -impl Habit { - pub fn toggle(&mut self, date: NaiveDate) { - if let Some(v) = self.stats.get_mut(&date) { - *v ^= true + pub fn modify(&mut self, date: NaiveDate, event: TrackEvent) { + if let Some(val) = self.stats.get_mut(&date) { + match val { + HabitType::Bit(b) => *b ^= true, + HabitType::Count(c) => match event { + TrackEvent::Increment => *c += 1, + TrackEvent::Decrement => { + if *c > 0 { + *c -= 1; + } else { + *c = 0; + } + } + }, + } } else { - self.insert_entry(date, true); + match self.goal { + HabitType::Bit(_) => self.insert_entry(date, HabitType::Bit(false)), + HabitType::Count(_) => self.insert_entry(date, HabitType::Count(0)), + } } } - pub fn reached_goal(&self, date: NaiveDate) -> bool { - *self.get_by_date(date).unwrap_or(&false) - } } -impl Habit { - pub fn increment(&mut self, date: NaiveDate) { - if let Some(v) = self.stats.get_mut(&date) { - *v += 1; - } else { - self.insert_entry(date, 1); - } +impl HabitTrait for Habit { + fn get_name(&self) -> String { + return self.name.to_owned(); } - pub fn decrement(&mut self, date: NaiveDate) { - if let Some(v) = self.stats.get_mut(&date) { - if *v > 0 { - *v -= 1; - } else { - *v = 0; - }; - } + fn set_name(&mut self, n: impl AsRef) { + self.name = n.as_ref().to_owned(); + } + fn set_goal(&mut self, g: HabitType) { + self.goal = g; } - pub fn set(&mut self, date: NaiveDate, val: u32) { + fn get_by_date(&self, date: NaiveDate) -> Option<&HabitType> { + self.stats.get(&date) + } + fn insert_entry(&mut self, date: NaiveDate, val: HabitType) { *self.stats.entry(date).or_insert(val) = val; } - pub fn reached_goal(&self, date: NaiveDate) -> bool { - if let Some(v) = self.get_by_date(date) { - if *v >= self.goal { - return true; - } + fn reached_goal(&self, date: NaiveDate) -> bool { + if let Some(val) = self.stats.get(&date) { + match val { + HabitType::Bit(b) => return *b, + HabitType::Count(c) => { + if *c >= self.goal.inner_count() { + return true; + } + } + }; } return false; } -- cgit v1.2.3