diff --git a/radicle-cob/src/change_graph.rs b/radicle-cob/src/change_graph.rs index 525fc256..a559f924 100644 --- a/radicle-cob/src/change_graph.rs +++ b/radicle-cob/src/change_graph.rs @@ -91,7 +91,7 @@ impl ChangeGraph { let manifest = root_node.manifest.clone(); let graph = self .graph - .fold(&root, Dag::new(), |mut graph, _, change, _| { + .fold(&[root], Dag::new(), |mut graph, _, change| { // Check the change signatures are valid. if !change.valid_signatures() { return ControlFlow::Break(graph); diff --git a/radicle-cob/src/history.rs b/radicle-cob/src/history.rs index fd7ca417..04f051c8 100644 --- a/radicle-cob/src/history.rs +++ b/radicle-cob/src/history.rs @@ -65,7 +65,7 @@ impl History { F: for<'r> FnMut(A, &'r EntryId, &'r Entry) -> ControlFlow, { self.graph - .fold(&self.root, init, |acc, k, v, _| f(acc, k, v)) + .fold(&[self.root], init, |acc, k, v| f(acc, k, v)) } /// Return a topologically-sorted list of history entries. diff --git a/radicle-dag/src/lib.rs b/radicle-dag/src/lib.rs index 33f1d3ef..7cf0f9a5 100644 --- a/radicle-dag/src/lib.rs +++ b/radicle-dag/src/lib.rs @@ -187,21 +187,21 @@ impl Dag { /// /// To continue traversing a branch, return [`ControlFlow::Continue`] from the /// filter function. To stop traversal of a branch, return [`ControlFlow::Break`]. - pub fn fold(&self, root: &K, mut acc: A, mut filter: F) -> A + pub fn fold(&self, roots: &[K], mut acc: A, mut filter: F) -> A where - F: for<'r> FnMut(A, &'r K, &'r Node, usize) -> ControlFlow, + F: for<'r> FnMut(A, &'r K, &'r Node) -> ControlFlow, { let mut visited = BTreeSet::new(); - let mut queue = VecDeque::<(K, usize)>::from([(*root, 0)]); + let mut queue = VecDeque::::from_iter(roots.iter().cloned()); - while let Some((next, depth)) = queue.pop_front() { + while let Some(next) = queue.pop_front() { if !visited.insert(next) { continue; } if let Some(node) = self.graph.get(&next) { - match filter(acc, &next, node, depth) { + match filter(acc, &next, node) { ControlFlow::Continue(a) => { - queue.extend(node.dependents.iter().map(|k| (*k, depth + 1))); + queue.extend(node.dependents.iter().cloned()); acc = a; } ControlFlow::Break(a) => { @@ -497,59 +497,13 @@ mod tests { dag.dependency("C1", "B2"); dag.dependency("C1", "B3"); - let acc = dag.fold(&"R", Vec::new(), |mut acc, key, _, _| { + let acc = dag.fold(&["R"], Vec::new(), |mut acc, key, _| { acc.push(*key); ControlFlow::Continue(acc) }); assert_eq!(acc, vec!["R", "A1", "A2", "A3", "B1", "B2", "B3", "C1"]); } - #[test] - fn test_fold_depth() { - let mut dag = Dag::new(); - - dag.node("R", ()); - dag.node("A1", ()); - dag.node("A2", ()); - dag.node("A3", ()); - dag.node("B1", ()); - dag.node("B2", ()); - dag.node("B3", ()); - dag.node("C1", ()); - - dag.dependency("A1", "R"); - dag.dependency("A2", "R"); - dag.dependency("A3", "R"); - - dag.dependency("B1", "A1"); - dag.dependency("B2", "A1"); - dag.dependency("B3", "A2"); - dag.dependency("B3", "A3"); - - dag.dependency("C1", "B1"); - dag.dependency("C1", "B2"); - dag.dependency("C1", "B3"); - - let acc = dag.fold(&"R", Vec::new(), |mut acc, key, _, depth| { - acc.push((*key, depth)); - ControlFlow::Continue(acc) - }); - - assert_eq!( - acc, - vec![ - ("R", 0), - ("A1", 1), - ("A2", 1), - ("A3", 1), - ("B1", 2), - ("B2", 2), - ("B3", 2), - ("C1", 3) - ] - ); - } - #[test] fn test_fold_reject() { let mut dag = Dag::new(); @@ -571,7 +525,7 @@ mod tests { let a1 = dag.get(&"A1").unwrap(); assert_eq!(dag.descendants_of(a1), vec!["B1", "C1", "D1"]); - let acc = dag.fold(&"R", Vec::new(), |mut acc, key, accept, _| { + let acc = dag.fold(&["R"], Vec::new(), |mut acc, key, accept| { if !accept.value { ControlFlow::Break(acc) } else {