diff options
-rw-r--r-- | src/habit.rs | 69 | ||||
-rw-r--r-- | src/main.rs | 30 |
2 files changed, 50 insertions, 49 deletions
diff --git a/src/habit.rs b/src/habit.rs index 45eeefa..13a2bd2 100644 --- a/src/habit.rs +++ b/src/habit.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::collections::HashMap; | 1 | use std::collections::HashMap; |
2 | 2 | ||
3 | use chrono::NaiveDate; | 3 | use chrono::NaiveDate; |
4 | use serde::Serialize; | 4 | use serde::{Deserialize, Serialize}; |
5 | 5 | ||
6 | use cursive::direction::Direction; | 6 | use cursive::direction::Direction; |
7 | use cursive::event::{Event, EventResult}; | 7 | use cursive::event::{Event, EventResult}; |
@@ -15,7 +15,7 @@ pub enum TrackEvent { | |||
15 | Decrement, | 15 | Decrement, |
16 | } | 16 | } |
17 | 17 | ||
18 | #[derive(Copy, Clone, Debug, Serialize)] | 18 | #[derive(Copy, Clone, Debug, Serialize, Deserialize)] |
19 | pub struct CustomBool(bool); | 19 | pub struct CustomBool(bool); |
20 | 20 | ||
21 | use std::fmt; | 21 | use std::fmt; |
@@ -53,6 +53,7 @@ pub trait Habit { | |||
53 | fn modify(&mut self, date: NaiveDate, event: TrackEvent); | 53 | fn modify(&mut self, date: NaiveDate, event: TrackEvent); |
54 | } | 54 | } |
55 | 55 | ||
56 | #[typetag::serde(tag = "type")] | ||
56 | pub trait HabitWrapper: erased_serde::Serialize { | 57 | pub trait HabitWrapper: erased_serde::Serialize { |
57 | fn remaining(&self, date: NaiveDate) -> u32; | 58 | fn remaining(&self, date: NaiveDate) -> u32; |
58 | fn total(&self) -> u32; | 59 | fn total(&self) -> u32; |
@@ -63,39 +64,39 @@ pub trait HabitWrapper: erased_serde::Serialize { | |||
63 | fn take_focus(&mut self, _: Direction) -> bool; | 64 | fn take_focus(&mut self, _: Direction) -> bool; |
64 | } | 65 | } |
65 | 66 | ||
66 | use erased_serde::serialize_trait_object; | 67 | macro_rules! auto_habit_impl { |
67 | serialize_trait_object!(HabitWrapper); | 68 | ($struct_name:ident) => { |
68 | 69 | #[typetag::serde] | |
69 | impl<T> HabitWrapper for T | 70 | impl HabitWrapper for $struct_name { |
70 | where | 71 | fn remaining(&self, date: NaiveDate) -> u32 { |
71 | T: Habit + ShadowView, | 72 | Habit::remaining(self, date) |
72 | T: Serialize, | 73 | } |
73 | T::HabitType: std::fmt::Display, | 74 | fn total(&self) -> u32 { |
74 | { | 75 | Habit::total(self) |
75 | fn remaining(&self, date: NaiveDate) -> u32 { | 76 | } |
76 | Habit::remaining(self, date) | 77 | fn modify(&mut self, date: NaiveDate, event: TrackEvent) { |
77 | } | 78 | Habit::modify(self, date, event); |
78 | fn total(&self) -> u32 { | 79 | } |
79 | Habit::total(self) | 80 | fn draw(&self, printer: &Printer) { |
80 | } | 81 | ShadowView::draw(self, printer) |
81 | fn modify(&mut self, date: NaiveDate, event: TrackEvent) { | 82 | } |
82 | Habit::modify(self, date, event); | 83 | fn on_event(&mut self, event: Event) -> EventResult { |
83 | } | 84 | ShadowView::on_event(self, event) |
84 | fn draw(&self, printer: &Printer) { | 85 | } |
85 | ShadowView::draw(self, printer) | 86 | fn required_size(&mut self, x: Vec2) -> Vec2 { |
86 | } | 87 | ShadowView::required_size(self, x) |
87 | fn on_event(&mut self, event: Event) -> EventResult { | 88 | } |
88 | ShadowView::on_event(self, event) | 89 | fn take_focus(&mut self, d: Direction) -> bool { |
89 | } | 90 | ShadowView::take_focus(self, d) |
90 | fn required_size(&mut self, x: Vec2) -> Vec2 { | 91 | } |
91 | ShadowView::required_size(self, x) | 92 | } |
92 | } | 93 | }; |
93 | fn take_focus(&mut self, d: Direction) -> bool { | ||
94 | ShadowView::take_focus(self, d) | ||
95 | } | ||
96 | } | 94 | } |
97 | 95 | ||
98 | #[derive(Debug, Serialize)] | 96 | auto_habit_impl!(Count); |
97 | auto_habit_impl!(Bit); | ||
98 | |||
99 | #[derive(Debug, Serialize, Deserialize)] | ||
99 | pub struct Count { | 100 | pub struct Count { |
100 | name: String, | 101 | name: String, |
101 | stats: HashMap<NaiveDate, u32>, | 102 | stats: HashMap<NaiveDate, u32>, |
@@ -170,7 +171,7 @@ impl Habit for Count { | |||
170 | } | 171 | } |
171 | } | 172 | } |
172 | 173 | ||
173 | #[derive(Debug, Serialize)] | 174 | #[derive(Debug, Serialize, Deserialize)] |
174 | pub struct Bit { | 175 | pub struct Bit { |
175 | name: String, | 176 | name: String, |
176 | stats: HashMap<NaiveDate, CustomBool>, | 177 | stats: HashMap<NaiveDate, CustomBool>, |
diff --git a/src/main.rs b/src/main.rs index cb3393b..2037a51 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -57,25 +57,25 @@ fn main() { | |||
57 | let mut s = Cursive::default(); | 57 | let mut s = Cursive::default(); |
58 | 58 | ||
59 | let mut gymming = Count::new("gym", 5); | 59 | let mut gymming = Count::new("gym", 5); |
60 | gymming.insert_entry(NaiveDate::from_ymd(2020, 3, 11), 7); | 60 | gymming.insert_entry(NaiveDate::from_ymd(2020, 4, 11), 7); |
61 | gymming.insert_entry(NaiveDate::from_ymd(2020, 3, 12), 8); | 61 | gymming.insert_entry(NaiveDate::from_ymd(2020, 4, 12), 8); |
62 | gymming.insert_entry(NaiveDate::from_ymd(2020, 3, 13), 9); | 62 | gymming.insert_entry(NaiveDate::from_ymd(2020, 4, 13), 9); |
63 | gymming.insert_entry(NaiveDate::from_ymd(2020, 3, 14), 10); | 63 | gymming.insert_entry(NaiveDate::from_ymd(2020, 4, 14), 10); |
64 | gymming.insert_entry(NaiveDate::from_ymd(2020, 3, 15), 11); | 64 | gymming.insert_entry(NaiveDate::from_ymd(2020, 4, 15), 11); |
65 | 65 | ||
66 | let mut reading = Bit::new("read"); | 66 | let mut reading = Bit::new("read"); |
67 | reading.insert_entry(NaiveDate::from_ymd(2020, 3, 11), true.into()); | 67 | reading.insert_entry(NaiveDate::from_ymd(2020, 4, 11), true.into()); |
68 | reading.insert_entry(NaiveDate::from_ymd(2020, 3, 12), false.into()); | 68 | reading.insert_entry(NaiveDate::from_ymd(2020, 4, 12), false.into()); |
69 | reading.insert_entry(NaiveDate::from_ymd(2020, 3, 13), true.into()); | 69 | reading.insert_entry(NaiveDate::from_ymd(2020, 4, 13), true.into()); |
70 | reading.insert_entry(NaiveDate::from_ymd(2020, 3, 14), false.into()); | 70 | reading.insert_entry(NaiveDate::from_ymd(2020, 4, 14), false.into()); |
71 | reading.insert_entry(NaiveDate::from_ymd(2020, 3, 15), true.into()); | 71 | reading.insert_entry(NaiveDate::from_ymd(2020, 4, 15), true.into()); |
72 | 72 | ||
73 | let mut walking = Bit::new("walk"); | 73 | let mut walking = Bit::new("walk"); |
74 | walking.insert_entry(NaiveDate::from_ymd(2020, 3, 11), true.into()); | 74 | walking.insert_entry(NaiveDate::from_ymd(2020, 4, 11), true.into()); |
75 | walking.insert_entry(NaiveDate::from_ymd(2020, 3, 12), false.into()); | 75 | walking.insert_entry(NaiveDate::from_ymd(2020, 4, 12), false.into()); |
76 | walking.insert_entry(NaiveDate::from_ymd(2020, 3, 13), true.into()); | 76 | walking.insert_entry(NaiveDate::from_ymd(2020, 4, 13), true.into()); |
77 | walking.insert_entry(NaiveDate::from_ymd(2020, 3, 14), false.into()); | 77 | walking.insert_entry(NaiveDate::from_ymd(2020, 4, 14), false.into()); |
78 | walking.insert_entry(NaiveDate::from_ymd(2020, 3, 15), true.into()); | 78 | walking.insert_entry(NaiveDate::from_ymd(2020, 4, 15), true.into()); |
79 | 79 | ||
80 | let mut app = App::new(); | 80 | let mut app = App::new(); |
81 | app.add_habit(Box::new(gymming)); | 81 | app.add_habit(Box::new(gymming)); |