forked from yewstack/yew
-
Notifications
You must be signed in to change notification settings - Fork 0
/
state.rs
executable file
·142 lines (126 loc) · 3.4 KB
/
state.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use serde_derive::{Deserialize, Serialize};
use strum_macros::{Display, EnumIter};
#[derive(Debug, Serialize, Deserialize)]
pub struct State {
pub entries: Vec<Entry>,
pub filter: Filter,
pub edit_value: String,
}
impl State {
pub fn total(&self) -> usize {
self.entries.len()
}
pub fn total_completed(&self) -> usize {
self.entries
.iter()
.filter(|e| Filter::Completed.fits(e))
.count()
}
pub fn is_all_completed(&self) -> bool {
let mut filtered_iter = self
.entries
.iter()
.filter(|e| self.filter.fits(e))
.peekable();
if filtered_iter.peek().is_none() {
return false;
}
filtered_iter.all(|e| e.completed)
}
pub fn clear_completed(&mut self) {
let entries = self
.entries
.drain(..)
.filter(|e| Filter::Active.fits(e))
.collect();
self.entries = entries;
}
pub fn toggle(&mut self, idx: usize) {
let filter = self.filter;
let entry = self
.entries
.iter_mut()
.filter(|e| filter.fits(e))
.nth(idx)
.unwrap();
entry.completed = !entry.completed;
}
pub fn toggle_all(&mut self, value: bool) {
for entry in &mut self.entries {
if self.filter.fits(entry) {
entry.completed = value;
}
}
}
pub fn toggle_edit(&mut self, idx: usize) {
let filter = self.filter;
let entry = self
.entries
.iter_mut()
.filter(|e| filter.fits(e))
.nth(idx)
.unwrap();
entry.editing = !entry.editing;
}
pub fn clear_all_edit(&mut self) {
for entry in &mut self.entries {
entry.editing = false;
}
}
pub fn complete_edit(&mut self, idx: usize, val: String) {
if val.is_empty() {
self.remove(idx);
} else {
let filter = self.filter;
let entry = self
.entries
.iter_mut()
.filter(|e| filter.fits(e))
.nth(idx)
.unwrap();
entry.description = val;
entry.editing = !entry.editing;
}
}
pub fn remove(&mut self, idx: usize) {
let idx = {
let entries = self
.entries
.iter()
.enumerate()
.filter(|&(_, e)| self.filter.fits(e))
.collect::<Vec<_>>();
let &(idx, _) = entries.get(idx).unwrap();
idx
};
self.entries.remove(idx);
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Entry {
pub description: String,
pub completed: bool,
pub editing: bool,
}
#[derive(Clone, Copy, Debug, EnumIter, Display, PartialEq, Serialize, Deserialize)]
pub enum Filter {
All,
Active,
Completed,
}
impl Filter {
pub fn fits(&self, entry: &Entry) -> bool {
match *self {
Filter::All => true,
Filter::Active => !entry.completed,
Filter::Completed => entry.completed,
}
}
pub fn as_href(&self) -> &'static str {
match self {
Filter::All => "#/",
Filter::Active => "#/active",
Filter::Completed => "#/completed",
}
}
}