refactor(tasks): resolve recursive tasks without intermediate collections

This commit is contained in:
xeruf 2024-08-16 09:45:35 +03:00
parent 34540370c3
commit 2fac3fd8f8
1 changed files with 23 additions and 27 deletions

View File

@ -298,39 +298,35 @@ impl Tasks {
// Helpers // Helpers
fn resolve_tasks<'a>(&self, iter: impl IntoIterator<Item=&'a EventId>) -> Vec<&Task> { fn resolve_tasks<'a>(&'a self, iter: impl Iterator<Item=&'a EventId>) -> impl Iterator<Item=&'a Task> {
self.resolve_tasks_rec(iter, self.depth) self.resolve_tasks_rec(iter, self.depth)
} }
fn resolve_tasks_rec<'a>( fn resolve_tasks_rec<'a>(
&self, &'a self,
iter: impl IntoIterator<Item=&'a EventId>, iter: impl Iterator<Item=&'a EventId>,
depth: i8, depth: i8,
) -> Vec<&Task> { ) -> Box<impl Iterator<Item=&'a Task>> {
iter.into_iter() iter.filter_map(|id| self.get_by_id(&id))
.filter_map(|id| self.get_by_id(&id)) .flat_map(move |task| {
.flat_map(|task| {
let new_depth = depth - 1; let new_depth = depth - 1;
if new_depth == 0 {
vec![task]
} else {
let tasks_iter = self.resolve_tasks_rec(task.children.iter(), new_depth);
if new_depth < 0 { if new_depth < 0 {
let tasks = self let tasks: Vec<&Task> = tasks_iter.collect();
.resolve_tasks_rec(task.children.iter(), new_depth)
.into_iter()
.collect::<Vec<&Task>>();
if tasks.is_empty() { if tasks.is_empty() {
vec![task] vec![task]
} else { } else {
tasks tasks
} }
} else if new_depth > 0 {
self.resolve_tasks_rec(task.children.iter(), new_depth)
.into_iter()
.chain(once(task))
.collect()
} else { } else {
vec![task] tasks_iter.chain(once(task)).collect()
}
} }
}) })
.collect() .into()
} }
pub(crate) fn referenced_tasks<F: Fn(&mut Task)>(&mut self, event: &Event, f: F) { pub(crate) fn referenced_tasks<F: Fn(&mut Task)>(&mut self, event: &Event, f: F) {
@ -354,8 +350,8 @@ impl Tasks {
} }
pub(crate) fn filtered_tasks(&self, position: Option<EventId>) -> impl Iterator<Item=&Task> { pub(crate) fn filtered_tasks(&self, position: Option<EventId>) -> impl Iterator<Item=&Task> {
// TODO use ChildrenIterator // TODO use ChildIterator
self.resolve_tasks(self.children_of(position)).into_iter() self.resolve_tasks(self.children_of(position))
.filter(|t| { .filter(|t| {
// TODO apply filters in transit // TODO apply filters in transit
self.state.matches(t) && self.state.matches(t) &&
@ -375,7 +371,7 @@ impl Tasks {
return self.get_current_task().into_iter().collect(); return self.get_current_task().into_iter().collect();
} }
if self.view.len() > 0 { if self.view.len() > 0 {
return self.resolve_tasks(self.view.iter()); return self.resolve_tasks(self.view.iter()).collect();
} }
self.filtered_tasks(self.position).collect() self.filtered_tasks(self.position).collect()
} }