fn edges_to_break_cycle<N: Clone + Hash + Eq, E: Clone>(
    graph: &Graph<N, E>,
) -> Vec<HashSet<(N, N)>> {
    let edge_sets = graph.edge_indices().powerset();
    let mut breaking_edge_sets = Vec::new();

    // For each DFS
    let mut cycle_detector = CycleDetector::new(graph);

    let mut minimal_break_point = usize::MAX;
    for edge_set in edge_sets {
        let set_size = edge_set.len();
        if set_size > minimal_break_point {
            break;
        }
        let trimmed_graph = EdgeFiltered::from_fn(graph, |edge| !edge_set.contains(&edge.id()));

        let is_cyclic = cycle_detector.has_cycle(&trimmed_graph, trimmed_graph.0.node_indices());
        if !is_cyclic {
            minimal_break_point = set_size;
            breaking_edge_sets.push(
                edge_set
                    .into_iter()
                    .map(|edge| {
                        let (src, dst) = graph.edge_endpoints(edge).unwrap();
                        (
                            graph.node_weight(src).unwrap().clone(),
                            graph.node_weight(dst).unwrap().clone(),
                        )
                    })
                    .collect(),
            );
        }
    }

    breaking_edge_sets
}
Given a graph that has a cycle, return all minimal sets of edges that result
in a cycle no longer being present.
Minimal here means that if the cycle can be broken by only removing n edges,
then only sets containing n edges will be returned.
crates/turborepo-graph-utils/src/lib.rs