Simplify the logic in reporter

This commit is contained in:
Campbell Alden 2023-07-21 19:39:52 +09:00
parent 79c2936766
commit 8ad7a2c4e6

View file

@ -18,101 +18,71 @@ pub struct AreaTree {
#[derive(Debug)] #[derive(Debug)]
pub struct ThingsTree { pub struct ThingsTree {
areas: Vec<AreaTree>, areas: Vec<AreaTree>,
hanging_projects: Vec<ProjectTree>,
hanging_tasks: Vec<Task>, hanging_tasks: Vec<Task>,
} }
impl ProjectTree {
/// Add the task to this project if it belongs here, otherwise pass it back out.
pub fn try_take_task(&mut self, mut task: Task) -> Option<Task> {
if let Some(proj) = task.project {
if proj.id == self.id {
task.project = Some(proj);
self.tasks.push(task);
return None;
}
task.project = Some(proj);
return Some(task);
}
return Some(task);
}
}
impl AreaTree { impl AreaTree {
pub fn add_new_project_and_task(&mut self, mut task: Task) { fn new(id: &str, title: &str) -> AreaTree {
if let Some(proj) = task.project { AreaTree {
let id = proj.id.clone(); id: id.clone().to_string(),
let title = proj.title.clone(); title: title.clone().to_string(),
task.project = Some(proj); projects: vec![],
hanging_tasks: vec![],
}
}
fn add_task(&mut self, task: Task) {
if let Some(project) = &task.project {
if let Some(matched_project) = self.projects.iter_mut().find(|p| p.id == project.id) {
matched_project.tasks.push(task);
} else {
self.projects.push(ProjectTree { self.projects.push(ProjectTree {
id, id: project.id.clone(),
title, title: project.title.clone(),
tasks: vec![task], tasks: vec![task],
}); });
}
} else { } else {
self.hanging_tasks.push(task); self.hanging_tasks.push(task);
} }
} }
pub fn try_take_task(&mut self, mut task: Task) -> Option<Task> {
if let Some(area) = task.area {
if area.id == self.id {
task.area = Some(area);
let mut maybe_task = Some(task);
for proj in self.projects.iter_mut() {
if let Some(t) = maybe_task {
maybe_task = proj.try_take_task(t);
}
}
// Here, the task belongs in this area but there was no project for it.
maybe_task.map(|t| self.add_new_project_and_task(t));
return None;
}
task.area = Some(area);
return Some(task);
}
return Some(task);
}
} }
impl ThingsTree { impl ThingsTree {
pub fn new() -> ThingsTree { pub fn new() -> ThingsTree {
ThingsTree { areas: vec![], hanging_tasks: vec![] } ThingsTree { areas: vec![], hanging_tasks: vec![], hanging_projects: vec![] }
} }
pub fn add_task(&mut self, task: Task) {
pub fn add_new_area_and_task(&mut self, mut task: Task) { if let Some(area) = &task.area {
if let Some(area) = task.area { if let Some(matched_area) = self.areas.iter_mut().find(|a| a.id == area.id) {
let id = area.id.clone(); matched_area.add_task(task);
let title = area.title.clone(); } else {
task.area = Some(area); let mut new_area = AreaTree::new(&area.id, &area.title);
let mut area_tree = AreaTree { new_area.add_task(task);
id, self.areas.push(new_area);
title, }
projects: vec![], } else {
hanging_tasks: vec![], if let Some(project) = &task.project {
}; if let Some(matched_project) = self.hanging_projects.iter_mut().find(|p| p.id == project.id) {
let took = area_tree.try_take_task(task); matched_project.tasks.push(task);
if took.is_some() { } else {
panic!("Area should have matched the task because it was created with the task"); self.hanging_projects.push(ProjectTree {
id: project.id.clone(),
title: project.title.clone(),
tasks: vec![task],
});
} }
self.areas.push(area_tree);
} else { } else {
self.hanging_tasks.push(task); self.hanging_tasks.push(task);
} }
} }
}
pub fn try_take_task(&mut self, task: Task) {
let mut maybe_task = Some(task);
for area in self.areas.iter_mut() {
if let Some(t) = maybe_task {
maybe_task = area.try_take_task(t);
}
}
maybe_task.map(|t| self.add_new_area_and_task(t));
}
pub fn from_tasks(tasks: Vec<Task>) -> ThingsTree { pub fn from_tasks(tasks: Vec<Task>) -> ThingsTree {
let mut tree = ThingsTree::new(); let mut tree = ThingsTree::new();
for task in tasks.into_iter() { for task in tasks.into_iter() {
tree.try_take_task(task); tree.add_task(task);
} }
return tree; return tree;
} }