From e4e05dd72187c22d7c51b216a16b6bb5d7e88572 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sun, 12 Jul 2020 20:27:35 +0530 Subject: refactor habit.rs into habit module --- src/habit.rs | 319 --------------------------------------------------- src/habit/bit.rs | 117 +++++++++++++++++++ src/habit/count.rs | 102 ++++++++++++++++ src/habit/mod.rs | 20 ++++ src/habit/prelude.rs | 20 ++++ src/habit/traits.rs | 94 +++++++++++++++ 6 files changed, 353 insertions(+), 319 deletions(-) delete mode 100644 src/habit.rs create mode 100644 src/habit/bit.rs create mode 100644 src/habit/count.rs create mode 100644 src/habit/mod.rs create mode 100644 src/habit/prelude.rs create mode 100644 src/habit/traits.rs diff --git a/src/habit.rs b/src/habit.rs deleted file mode 100644 index 725e15f..0000000 --- a/src/habit.rs +++ /dev/null @@ -1,319 +0,0 @@ -use std::collections::HashMap; - -use chrono::NaiveDate; -use serde::{Deserialize, Serialize}; - -use cursive::direction::Direction; -use cursive::event::{Event, EventResult}; -use cursive::{Printer, Vec2}; - -use crate::views::ShadowView; -use crate::CONFIGURATION; - -pub enum TrackEvent { - Increment, - Decrement, -} - -#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] -pub enum ViewMode { - Day, - Week, - Month, - Year, -} - -impl std::default::Default for ViewMode { - fn default() -> Self { - ViewMode::Day - } -} - -#[derive(Copy, Clone, Debug, Serialize, Deserialize)] -pub struct CustomBool(bool); - -use std::fmt; -impl fmt::Display for CustomBool { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{:^3}", - if self.0 { - CONFIGURATION.true_chr - } else { - CONFIGURATION.false_chr - } - ) - } -} - -impl From for CustomBool { - fn from(b: bool) -> Self { - CustomBool(b) - } -} - -pub trait Habit { - type HabitType; - - fn set_name(&mut self, name: impl AsRef); - fn set_goal(&mut self, goal: Self::HabitType); - fn name(&self) -> String; - fn get_by_date(&self, date: NaiveDate) -> Option<&Self::HabitType>; - fn insert_entry(&mut self, date: NaiveDate, val: Self::HabitType); - fn reached_goal(&self, date: NaiveDate) -> bool; - fn remaining(&self, date: NaiveDate) -> u32; - fn goal(&self) -> u32; - fn modify(&mut self, date: NaiveDate, event: TrackEvent); - - fn set_view_month_offset(&mut self, offset: u32); - fn view_month_offset(&self) -> u32; - - fn set_view_mode(&mut self, mode: ViewMode); - fn view_mode(&self) -> ViewMode; -} - -#[typetag::serde(tag = "type")] -pub trait HabitWrapper: erased_serde::Serialize { - fn remaining(&self, date: NaiveDate) -> u32; - fn goal(&self) -> u32; - fn modify(&mut self, date: NaiveDate, event: TrackEvent); - fn draw(&self, printer: &Printer); - fn on_event(&mut self, event: Event) -> EventResult; - fn required_size(&mut self, _: Vec2) -> Vec2; - fn take_focus(&mut self, _: Direction) -> bool; - fn get_name(&self) -> String; - - fn set_view_month_offset(&mut self, offset: u32); - fn view_month_offset(&self) -> u32; - - fn set_view_mode(&mut self, mode: ViewMode); - fn view_mode(&self) -> ViewMode; -} - -macro_rules! auto_habit_impl { - ($struct_name:ident) => { - #[typetag::serde] - impl HabitWrapper for $struct_name { - fn remaining(&self, date: NaiveDate) -> u32 { - Habit::remaining(self, date) - } - fn goal(&self) -> u32 { - Habit::goal(self) - } - fn modify(&mut self, date: NaiveDate, event: TrackEvent) { - Habit::modify(self, date, event); - } - fn draw(&self, printer: &Printer) { - ShadowView::draw(self, printer) - } - fn on_event(&mut self, event: Event) -> EventResult { - ShadowView::on_event(self, event) - } - fn required_size(&mut self, x: Vec2) -> Vec2 { - ShadowView::required_size(self, x) - } - fn take_focus(&mut self, d: Direction) -> bool { - ShadowView::take_focus(self, d) - } - fn get_name(&self) -> String { - Habit::name(self) - } - fn set_view_month_offset(&mut self, offset: u32) { - Habit::set_view_month_offset(self, offset) - } - fn view_month_offset(&self) -> u32 { - Habit::view_month_offset(self) - } - fn set_view_mode(&mut self, mode: ViewMode) { - Habit::set_view_mode(self, mode) - } - fn view_mode(&self) -> ViewMode { - Habit::view_mode(self) - } - } - }; -} - -auto_habit_impl!(Count); -auto_habit_impl!(Bit); - -#[derive(Debug, Serialize, Deserialize)] -pub struct Count { - name: String, - stats: HashMap, - goal: u32, - - #[serde(skip)] - view_month_offset: u32, - - #[serde(skip)] - view_mode: ViewMode, -} - -impl Count { - pub fn new(name: impl AsRef, goal: u32) -> Self { - return Count { - name: name.as_ref().to_owned(), - stats: HashMap::new(), - goal, - view_month_offset: 0, - view_mode: ViewMode::Day, - }; - } -} - -impl Habit for Count { - type HabitType = u32; - - fn name(&self) -> String { - return self.name.clone(); - } - fn set_name(&mut self, n: impl AsRef) { - self.name = n.as_ref().to_owned(); - } - fn set_goal(&mut self, g: Self::HabitType) { - self.goal = g; - } - fn get_by_date(&self, date: NaiveDate) -> Option<&Self::HabitType> { - self.stats.get(&date) - } - fn insert_entry(&mut self, date: NaiveDate, val: Self::HabitType) { - *self.stats.entry(date).or_insert(val) = val; - } - fn reached_goal(&self, date: NaiveDate) -> bool { - if let Some(val) = self.stats.get(&date) { - if val >= &self.goal { - return true; - } - } - return false; - } - fn remaining(&self, date: NaiveDate) -> u32 { - if self.reached_goal(date) { - return 0; - } else { - if let Some(val) = self.stats.get(&date) { - return self.goal - val; - } else { - return self.goal; - } - } - } - fn goal(&self) -> u32 { - return self.goal; - } - fn modify(&mut self, date: NaiveDate, event: TrackEvent) { - if let Some(val) = self.stats.get_mut(&date) { - match event { - TrackEvent::Increment => *val += 1, - TrackEvent::Decrement => { - if *val > 0 { - *val -= 1 - } else { - *val = 0 - }; - } - } - } else { - self.insert_entry(date, 1); - } - } - fn set_view_month_offset(&mut self, offset: u32) { - self.view_month_offset = offset; - } - fn view_month_offset(&self) -> u32 { - self.view_month_offset - } - fn set_view_mode(&mut self, mode: ViewMode) { - self.view_mode = mode; - } - fn view_mode(&self) -> ViewMode { - self.view_mode - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct Bit { - name: String, - stats: HashMap, - goal: CustomBool, - - #[serde(skip)] - view_month_offset: u32, - - #[serde(skip)] - view_mode: ViewMode, -} - -impl Bit { - pub fn new(name: impl AsRef) -> Self { - return Bit { - name: name.as_ref().to_owned(), - stats: HashMap::new(), - goal: CustomBool(true), - view_month_offset: 0, - view_mode: ViewMode::Day, - }; - } -} - -impl Habit for Bit { - type HabitType = CustomBool; - fn name(&self) -> String { - return self.name.clone(); - } - fn set_name(&mut self, n: impl AsRef) { - self.name = n.as_ref().to_owned(); - } - fn set_goal(&mut self, g: Self::HabitType) { - self.goal = g; - } - fn get_by_date(&self, date: NaiveDate) -> Option<&Self::HabitType> { - self.stats.get(&date) - } - fn insert_entry(&mut self, date: NaiveDate, val: Self::HabitType) { - *self.stats.entry(date).or_insert(val) = val; - } - fn reached_goal(&self, date: NaiveDate) -> bool { - if let Some(val) = self.stats.get(&date) { - if val.0 >= self.goal.0 { - return true; - } - } - return false; - } - fn remaining(&self, date: NaiveDate) -> u32 { - if let Some(val) = self.stats.get(&date) { - if val.0 { - return 0; - } else { - return 1; - } - } else { - return 1; - } - } - fn goal(&self) -> u32 { - return 1; - } - fn modify(&mut self, date: NaiveDate, _: TrackEvent) { - if let Some(val) = self.stats.get_mut(&date) { - *val = (val.0 ^ true).into(); - } else { - self.insert_entry(date, CustomBool(true)); - } - } - fn set_view_month_offset(&mut self, offset: u32) { - self.view_month_offset = offset; - } - fn view_month_offset(&self) -> u32 { - self.view_month_offset - } - fn set_view_mode(&mut self, mode: ViewMode) { - self.view_mode = mode; - } - fn view_mode(&self) -> ViewMode { - self.view_mode - } -} diff --git a/src/habit/bit.rs b/src/habit/bit.rs new file mode 100644 index 0000000..292b96a --- /dev/null +++ b/src/habit/bit.rs @@ -0,0 +1,117 @@ +use std::collections::HashMap; + +use chrono::NaiveDate; +use serde::{Deserialize, Serialize}; + +use crate::habit::traits::Habit; +use crate::habit::{TrackEvent, ViewMode}; +use crate::CONFIGURATION; + +#[derive(Copy, Clone, Debug, Serialize, Deserialize)] +pub struct CustomBool(bool); + +use std::fmt; +impl fmt::Display for CustomBool { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{:^3}", + if self.0 { + CONFIGURATION.true_chr + } else { + CONFIGURATION.false_chr + } + ) + } +} + +impl From for CustomBool { + fn from(b: bool) -> Self { + CustomBool(b) + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Bit { + name: String, + stats: HashMap, + goal: CustomBool, + + #[serde(skip)] + view_month_offset: u32, + + #[serde(skip)] + view_mode: ViewMode, +} + +impl Bit { + pub fn new(name: impl AsRef) -> Self { + return Bit { + name: name.as_ref().to_owned(), + stats: HashMap::new(), + goal: CustomBool(true), + view_month_offset: 0, + view_mode: ViewMode::Day, + }; + } +} + +impl Habit for Bit { + type HabitType = CustomBool; + fn name(&self) -> String { + return self.name.clone(); + } + fn set_name(&mut self, n: impl AsRef) { + self.name = n.as_ref().to_owned(); + } + fn set_goal(&mut self, g: Self::HabitType) { + self.goal = g; + } + fn get_by_date(&self, date: NaiveDate) -> Option<&Self::HabitType> { + self.stats.get(&date) + } + fn insert_entry(&mut self, date: NaiveDate, val: Self::HabitType) { + *self.stats.entry(date).or_insert(val) = val; + } + fn reached_goal(&self, date: NaiveDate) -> bool { + if let Some(val) = self.stats.get(&date) { + if val.0 >= self.goal.0 { + return true; + } + } + return false; + } + fn remaining(&self, date: NaiveDate) -> u32 { + if let Some(val) = self.stats.get(&date) { + if val.0 { + return 0; + } else { + return 1; + } + } else { + return 1; + } + } + fn goal(&self) -> u32 { + return 1; + } + fn modify(&mut self, date: NaiveDate, _: TrackEvent) { + if let Some(val) = self.stats.get_mut(&date) { + *val = (val.0 ^ true).into(); + } else { + self.insert_entry(date, CustomBool(true)); + } + } + fn set_view_month_offset(&mut self, offset: u32) { + self.view_month_offset = offset; + } + fn view_month_offset(&self) -> u32 { + self.view_month_offset + } + fn set_view_mode(&mut self, mode: ViewMode) { + self.view_mode = mode; + } + fn view_mode(&self) -> ViewMode { + self.view_mode + } +} diff --git a/src/habit/count.rs b/src/habit/count.rs new file mode 100644 index 0000000..a0e0aee --- /dev/null +++ b/src/habit/count.rs @@ -0,0 +1,102 @@ +use std::collections::HashMap; + +use chrono::NaiveDate; +use serde::{Deserialize, Serialize}; + +use crate::habit::traits::Habit; +use crate::habit::{TrackEvent, ViewMode}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Count { + name: String, + stats: HashMap, + goal: u32, + + #[serde(skip)] + view_month_offset: u32, + + #[serde(skip)] + view_mode: ViewMode, +} + +impl Count { + pub fn new(name: impl AsRef, goal: u32) -> Self { + return Count { + name: name.as_ref().to_owned(), + stats: HashMap::new(), + goal, + view_month_offset: 0, + view_mode: ViewMode::Day, + }; + } +} + +impl Habit for Count { + type HabitType = u32; + + fn name(&self) -> String { + return self.name.clone(); + } + fn set_name(&mut self, n: impl AsRef) { + self.name = n.as_ref().to_owned(); + } + fn set_goal(&mut self, g: Self::HabitType) { + self.goal = g; + } + fn get_by_date(&self, date: NaiveDate) -> Option<&Self::HabitType> { + self.stats.get(&date) + } + fn insert_entry(&mut self, date: NaiveDate, val: Self::HabitType) { + *self.stats.entry(date).or_insert(val) = val; + } + fn reached_goal(&self, date: NaiveDate) -> bool { + if let Some(val) = self.stats.get(&date) { + if val >= &self.goal { + return true; + } + } + return false; + } + fn remaining(&self, date: NaiveDate) -> u32 { + if self.reached_goal(date) { + return 0; + } else { + if let Some(val) = self.stats.get(&date) { + return self.goal - val; + } else { + return self.goal; + } + } + } + fn goal(&self) -> u32 { + return self.goal; + } + fn modify(&mut self, date: NaiveDate, event: TrackEvent) { + if let Some(val) = self.stats.get_mut(&date) { + match event { + TrackEvent::Increment => *val += 1, + TrackEvent::Decrement => { + if *val > 0 { + *val -= 1 + } else { + *val = 0 + }; + } + } + } else { + self.insert_entry(date, 1); + } + } + fn set_view_month_offset(&mut self, offset: u32) { + self.view_month_offset = offset; + } + fn view_month_offset(&self) -> u32 { + self.view_month_offset + } + fn set_view_mode(&mut self, mode: ViewMode) { + self.view_mode = mode; + } + fn view_mode(&self) -> ViewMode { + self.view_mode + } +} diff --git a/src/habit/mod.rs b/src/habit/mod.rs new file mode 100644 index 0000000..482ca06 --- /dev/null +++ b/src/habit/mod.rs @@ -0,0 +1,20 @@ +use std::collections::HashMap; + +use chrono::NaiveDate; +use serde::{Deserialize, Serialize}; + +use cursive::direction::Direction; +use cursive::event::{Event, EventResult}; +use cursive::{Printer, Vec2}; + +mod traits; +pub use traits::{Habit, HabitWrapper}; + +mod count; +pub use count::Count; + +mod bit; +pub use bit::Bit; + +mod prelude; +pub use prelude::{TrackEvent, ViewMode}; diff --git a/src/habit/prelude.rs b/src/habit/prelude.rs new file mode 100644 index 0000000..9196f00 --- /dev/null +++ b/src/habit/prelude.rs @@ -0,0 +1,20 @@ +use serde::{Deserialize, Serialize}; + +pub enum TrackEvent { + Increment, + Decrement, +} + +#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] +pub enum ViewMode { + Day, + Week, + Month, + Year, +} + +impl std::default::Default for ViewMode { + fn default() -> Self { + ViewMode::Day + } +} diff --git a/src/habit/traits.rs b/src/habit/traits.rs new file mode 100644 index 0000000..e28e55d --- /dev/null +++ b/src/habit/traits.rs @@ -0,0 +1,94 @@ +use chrono::NaiveDate; +use cursive::direction::Direction; +use cursive::event::{Event, EventResult}; +use cursive::{Printer, Vec2}; + +use typetag; + +use crate::habit::{Bit, Count, TrackEvent, ViewMode}; +use crate::views::ShadowView; + +pub trait Habit { + type HabitType; + + fn set_name(&mut self, name: impl AsRef); + fn set_goal(&mut self, goal: Self::HabitType); + fn name(&self) -> String; + fn get_by_date(&self, date: NaiveDate) -> Option<&Self::HabitType>; + fn insert_entry(&mut self, date: NaiveDate, val: Self::HabitType); + fn reached_goal(&self, date: NaiveDate) -> bool; + fn remaining(&self, date: NaiveDate) -> u32; + fn goal(&self) -> u32; + fn modify(&mut self, date: NaiveDate, event: TrackEvent); + + fn set_view_month_offset(&mut self, offset: u32); + fn view_month_offset(&self) -> u32; + + fn set_view_mode(&mut self, mode: ViewMode); + fn view_mode(&self) -> ViewMode; +} + +#[typetag::serde(tag = "type")] +pub trait HabitWrapper: erased_serde::Serialize { + fn remaining(&self, date: NaiveDate) -> u32; + fn goal(&self) -> u32; + fn modify(&mut self, date: NaiveDate, event: TrackEvent); + fn draw(&self, printer: &Printer); + fn on_event(&mut self, event: Event) -> EventResult; + fn required_size(&mut self, _: Vec2) -> Vec2; + fn take_focus(&mut self, _: Direction) -> bool; + fn get_name(&self) -> String; + + fn set_view_month_offset(&mut self, offset: u32); + fn view_month_offset(&self) -> u32; + + fn set_view_mode(&mut self, mode: ViewMode); + fn view_mode(&self) -> ViewMode; +} + +macro_rules! auto_habit_impl { + ($struct_name:ident) => { + #[typetag::serde] + impl HabitWrapper for $struct_name { + fn remaining(&self, date: NaiveDate) -> u32 { + Habit::remaining(self, date) + } + fn goal(&self) -> u32 { + Habit::goal(self) + } + fn modify(&mut self, date: NaiveDate, event: TrackEvent) { + Habit::modify(self, date, event); + } + fn draw(&self, printer: &Printer) { + ShadowView::draw(self, printer) + } + fn on_event(&mut self, event: Event) -> EventResult { + ShadowView::on_event(self, event) + } + fn required_size(&mut self, x: Vec2) -> Vec2 { + ShadowView::required_size(self, x) + } + fn take_focus(&mut self, d: Direction) -> bool { + ShadowView::take_focus(self, d) + } + fn get_name(&self) -> String { + Habit::name(self) + } + fn set_view_month_offset(&mut self, offset: u32) { + Habit::set_view_month_offset(self, offset) + } + fn view_month_offset(&self) -> u32 { + Habit::view_month_offset(self) + } + fn set_view_mode(&mut self, mode: ViewMode) { + Habit::set_view_mode(self, mode) + } + fn view_mode(&self) -> ViewMode { + Habit::view_mode(self) + } + } + }; +} + +auto_habit_impl!(Count); +auto_habit_impl!(Bit); -- cgit v1.2.3