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
use std::path::Path;
pub mod error;
mod storage;
pub mod task;
pub mod project;
use task::{task_f, Task};
use project::Project;
fn list_filter<F>(path: &Path, project: Option<String>, op: F) -> Result<(), error::Error>
where
F: Fn(&usize, &Task) -> bool,
{
let projects = storage::load_tasks(&path)?;
match project {
None => {
let projs = storage::load_tasks(&path)?;
for (i, proj) in projs.iter().enumerate() {
println!("{}", proj);
proj.tasks()
.iter()
.enumerate()
.filter(|(i, t)| op(i, *t))
.for_each(|(idx, t)| println!("[{}]: {}", idx, t));
if i != projs.len() - 1 {
println!("");
}
}
Ok(())
},
Some(name) => {
if let Some(idx) = projects.iter().position(|p| p.name == name) {
println!("{}", projects[idx]);
projects[idx]
.tasks()
.iter()
.enumerate()
.filter(|(i, t)| op(i, *t))
.for_each(|(idx, t)| println!("[{}]: {}", idx, t));
Ok(())
} else {
Err(error::Error::ProjectNotFound(name))
}
}
}
}
pub fn list_all(path: &Path, project: Option<String>) -> Result<(), error::Error> {
list_filter(path, project, |_a, _b| true)
}
pub fn list(path: &Path, project: Option<String>) -> Result<(), error::Error> {
list_filter(path, project, |_, t| task_f(&t))
}
pub fn rename(path: &Path, project: String, name: String) -> Result<(), error::Error> {
let mut projs = storage::load_tasks(&path)?;
if let Some(idx) = projs.iter().position(|p| p.name == project) {
if projs.iter().any(|p| p.name == name) {
return Err(error::Error::ProjectNameTaken(name))
}
projs[idx].rename(name);
} else {
return Err(error::Error::ProjectNotFound(project))
}
storage::store_tasks(&path, &projs)
}
pub fn add_task(path: &Path, task: Task, name: String) -> Result<(), error::Error> {
let mut projs = storage::load_tasks(&path)?;
if let Some(idx) = projs.iter().position(|p| p.name == name) {
projs[idx].push(task);
} else {
let mut p = Project::new(name);
p.push(task);
projs.push(p);
projs.sort();
}
storage::store_tasks(&path, &projs)
}
pub fn remove_task(path: &Path, id: usize, name: String) -> Result<Task, error::Error> {
let mut projs = storage::load_tasks(&path)?;
let idx_res = projs.iter().position(|p| p.name == name);
if idx_res.is_none() {
return Err(error::Error::ProjectNotFound(name))
}
let idx = idx_res.unwrap();
let task = projs[idx].remove(id)?;
if projs[idx].len() == 0 {
projs.remove(idx);
}
storage::store_tasks(&path, &projs)?;
Ok(task)
}
pub fn move_task(path: &Path, old_project: String, id: usize, new_project: String) -> Result<(), error::Error> {
let task = remove_task(path, id, old_project)?;
add_task(path, task, new_project)
}
pub fn edit_task(path: &Path, id: usize, name: String, desc: Option<String>, prio: Option<task::Priority>) -> Result<(), error::Error> {
let mut projs = storage::load_tasks(&path)?;
let idx_res = projs.iter().position(|p| p.name == name);
if idx_res.is_none() {
return Err(error::Error::ProjectNotFound(name))
}
let idx = idx_res.unwrap();
projs[idx].edit(id, desc, prio)?;
storage::store_tasks(&path, &projs)?;
Ok(())
}