use hashbrown::HashMap; use petgraph::graph::{DiGraph, NodeIndex}; use petgraph::algo::{condensation, toposort}; use super::*; struct GraphBuilder<'ctx> { ctx: &'ctx DowngradeContext, graph: DiGraph, nodes: HashMap } impl GraphBuilder<'_> { fn connect(&mut self, idx: usize) { let node = self.graph.add_node(idx); self.nodes.insert(idx, node); let deps = self.ctx.thunk_deps.get(idx).unwrap(); for (&refee, _) in deps { if !self.nodes.contains_key(&refee) { self.connect(refee); } self.graph.add_edge(node, *self.nodes.get(&refee).unwrap(), ()); } } } pub fn sort_dependencies(ctx: &DowngradeContext) -> Vec> { let mut builder = GraphBuilder { ctx, graph: DiGraph::new(), nodes: HashMap::new(), }; builder.connect(ctx.thunks.len() - 1); let mut graph = condensation(builder.graph, false); let sorted = toposort(&graph, None).unwrap(); sorted.into_iter().map(|idx| graph.remove_node(idx).unwrap()).collect_vec() }