diff options
author | Akshay <[email protected]> | 2020-02-10 15:26:22 +0000 |
---|---|---|
committer | Akshay <[email protected]> | 2020-02-10 15:26:22 +0000 |
commit | d33e960c57fda3fa1c916ad765e32a673524d55e (patch) | |
tree | be1309658c397a61c4c582ca54d7d4e54bad64c3 | |
parent | 1b4fb7eb887b2fd581db6a6a961a246f01f49e07 (diff) |
move structs out
-rw-r--r-- | src/habit.rs | 63 | ||||
-rw-r--r-- | src/views.rs | 80 |
2 files changed, 143 insertions, 0 deletions
diff --git a/src/habit.rs b/src/habit.rs new file mode 100644 index 0000000..4f05217 --- /dev/null +++ b/src/habit.rs | |||
@@ -0,0 +1,63 @@ | |||
1 | use std::collections::HashMap; | ||
2 | |||
3 | use chrono::NaiveDate; | ||
4 | |||
5 | #[derive(Debug)] | ||
6 | pub struct Habit<T> { | ||
7 | name: String, | ||
8 | stats: HashMap<NaiveDate, T>, | ||
9 | } | ||
10 | |||
11 | impl<T> Habit<T> | ||
12 | where | ||
13 | T: Copy, | ||
14 | { | ||
15 | pub fn new(name: &str) -> Habit<T> { | ||
16 | return Habit { | ||
17 | name: name.to_owned(), | ||
18 | stats: HashMap::new(), | ||
19 | }; | ||
20 | } | ||
21 | |||
22 | pub fn get_name(&self) -> String { | ||
23 | return self.name.to_owned(); | ||
24 | } | ||
25 | |||
26 | pub fn get_by_date(&self, date: NaiveDate) -> Option<&T> { | ||
27 | self.stats.get(&date) | ||
28 | } | ||
29 | |||
30 | pub fn insert_entry(&mut self, date: NaiveDate, val: T) { | ||
31 | *self.stats.entry(date).or_insert(val) = val; | ||
32 | } | ||
33 | } | ||
34 | |||
35 | impl Habit<bool> { | ||
36 | pub fn toggle(&mut self, date: NaiveDate) { | ||
37 | if let Some(v) = self.stats.get_mut(&date) { | ||
38 | *v ^= true | ||
39 | } else { | ||
40 | self.insert_entry(date, true); | ||
41 | } | ||
42 | } | ||
43 | } | ||
44 | |||
45 | impl Habit<u32> { | ||
46 | pub fn increment(&mut self, date: NaiveDate) { | ||
47 | if let Some(v) = self.stats.get_mut(&date) { | ||
48 | *v += 1 | ||
49 | } | ||
50 | } | ||
51 | pub fn decrement(&mut self, date: NaiveDate) { | ||
52 | if let Some(v) = self.stats.get_mut(&date) { | ||
53 | if *v >= 1 { | ||
54 | *v -= 1; | ||
55 | } else { | ||
56 | *v = 0; | ||
57 | }; | ||
58 | } | ||
59 | } | ||
60 | pub fn set(&mut self, date: NaiveDate, val: u32) { | ||
61 | *self.stats.entry(date).or_insert(val) = val; | ||
62 | } | ||
63 | } | ||
diff --git a/src/views.rs b/src/views.rs new file mode 100644 index 0000000..5b9ec20 --- /dev/null +++ b/src/views.rs | |||
@@ -0,0 +1,80 @@ | |||
1 | use cursive::direction::Direction; | ||
2 | use cursive::event::{Event, EventResult, Key}; | ||
3 | use cursive::view::View; | ||
4 | use cursive::{Printer, Vec2}; | ||
5 | |||
6 | use chrono::prelude::*; | ||
7 | use chrono::{Local, NaiveDate}; | ||
8 | |||
9 | use crate::habit::Habit; | ||
10 | |||
11 | pub struct BitView { | ||
12 | habit: Habit<bool>, | ||
13 | true_chr: char, | ||
14 | false_chr: char, | ||
15 | future_chr: char, | ||
16 | |||
17 | view_width: u32, | ||
18 | view_height: u32, | ||
19 | // color config | ||
20 | } | ||
21 | |||
22 | impl BitView { | ||
23 | pub fn new(habit: Habit<bool>) -> Self { | ||
24 | return BitView { | ||
25 | habit, | ||
26 | true_chr: 'x', | ||
27 | false_chr: 'o', | ||
28 | future_chr: '.', | ||
29 | view_width: 21, | ||
30 | view_height: 9, | ||
31 | }; | ||
32 | } | ||
33 | pub fn get_title(&self) -> String { | ||
34 | return self.habit.get_name().to_owned(); | ||
35 | } | ||
36 | } | ||
37 | |||
38 | impl View for BitView { | ||
39 | fn draw(&self, printer: &Printer) { | ||
40 | let now = Local::now(); | ||
41 | let year = now.year(); | ||
42 | let month = now.month(); | ||
43 | |||
44 | for i in 1..=31 { | ||
45 | let day = NaiveDate::from_ymd_opt(year, month, i); | ||
46 | if let Some(d) = day { | ||
47 | let day_status = self.habit.get_by_date(d).unwrap_or(&false); | ||
48 | let coords = ((i % 7) * 3, i / 7 + 2); | ||
49 | |||
50 | if d <= now.naive_utc().date() { | ||
51 | if *day_status { | ||
52 | printer.print(coords, &format!("{:^3}", self.true_chr)) | ||
53 | } else { | ||
54 | printer.print(coords, &format!("{:^3}", self.false_chr)) | ||
55 | } | ||
56 | } else { | ||
57 | printer.print(coords, &format!("{:^3}", self.future_chr)) | ||
58 | } | ||
59 | } | ||
60 | } | ||
61 | } | ||
62 | |||
63 | fn required_size(&mut self, _: Vec2) -> Vec2 { | ||
64 | (20, 9).into() | ||
65 | } | ||
66 | |||
67 | fn take_focus(&mut self, _: Direction) -> bool { | ||
68 | true | ||
69 | } | ||
70 | |||
71 | fn on_event(&mut self, e: Event) -> EventResult { | ||
72 | match e { | ||
73 | Event::Key(Key::Enter) => { | ||
74 | self.habit.toggle(Local::now().naive_utc().date()); | ||
75 | return EventResult::Consumed(None); | ||
76 | } | ||
77 | _ => return EventResult::Ignored, | ||
78 | } | ||
79 | } | ||
80 | } | ||