aboutsummaryrefslogtreecommitdiff
path: root/src/habit/bit.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/habit/bit.rs')
-rw-r--r--src/habit/bit.rs117
1 files changed, 117 insertions, 0 deletions
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 @@
1use std::collections::HashMap;
2
3use chrono::NaiveDate;
4use serde::{Deserialize, Serialize};
5
6use crate::habit::traits::Habit;
7use crate::habit::{TrackEvent, ViewMode};
8use crate::CONFIGURATION;
9
10#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
11pub struct CustomBool(bool);
12
13use std::fmt;
14impl fmt::Display for CustomBool {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 write!(
17 f,
18 "{:^3}",
19 if self.0 {
20 CONFIGURATION.true_chr
21 } else {
22 CONFIGURATION.false_chr
23 }
24 )
25 }
26}
27
28impl From<bool> for CustomBool {
29 fn from(b: bool) -> Self {
30 CustomBool(b)
31 }
32}
33
34#[derive(Debug, Serialize, Deserialize)]
35pub struct Bit {
36 name: String,
37 stats: HashMap<NaiveDate, CustomBool>,
38 goal: CustomBool,
39
40 #[serde(skip)]
41 view_month_offset: u32,
42
43 #[serde(skip)]
44 view_mode: ViewMode,
45}
46
47impl Bit {
48 pub fn new(name: impl AsRef<str>) -> Self {
49 return Bit {
50 name: name.as_ref().to_owned(),
51 stats: HashMap::new(),
52 goal: CustomBool(true),
53 view_month_offset: 0,
54 view_mode: ViewMode::Day,
55 };
56 }
57}
58
59impl Habit for Bit {
60 type HabitType = CustomBool;
61 fn name(&self) -> String {
62 return self.name.clone();
63 }
64 fn set_name(&mut self, n: impl AsRef<str>) {
65 self.name = n.as_ref().to_owned();
66 }
67 fn set_goal(&mut self, g: Self::HabitType) {
68 self.goal = g;
69 }
70 fn get_by_date(&self, date: NaiveDate) -> Option<&Self::HabitType> {
71 self.stats.get(&date)
72 }
73 fn insert_entry(&mut self, date: NaiveDate, val: Self::HabitType) {
74 *self.stats.entry(date).or_insert(val) = val;
75 }
76 fn reached_goal(&self, date: NaiveDate) -> bool {
77 if let Some(val) = self.stats.get(&date) {
78 if val.0 >= self.goal.0 {
79 return true;
80 }
81 }
82 return false;
83 }
84 fn remaining(&self, date: NaiveDate) -> u32 {
85 if let Some(val) = self.stats.get(&date) {
86 if val.0 {
87 return 0;
88 } else {
89 return 1;
90 }
91 } else {
92 return 1;
93 }
94 }
95 fn goal(&self) -> u32 {
96 return 1;
97 }
98 fn modify(&mut self, date: NaiveDate, _: TrackEvent) {
99 if let Some(val) = self.stats.get_mut(&date) {
100 *val = (val.0 ^ true).into();
101 } else {
102 self.insert_entry(date, CustomBool(true));
103 }
104 }
105 fn set_view_month_offset(&mut self, offset: u32) {
106 self.view_month_offset = offset;
107 }
108 fn view_month_offset(&self) -> u32 {
109 self.view_month_offset
110 }
111 fn set_view_mode(&mut self, mode: ViewMode) {
112 self.view_mode = mode;
113 }
114 fn view_mode(&self) -> ViewMode {
115 self.view_mode
116 }
117}