Skip to content

Commit 712f984

Browse files
committed
refactor(tree): Abstract the concept of an Edge
1 parent 6bfa8c7 commit 712f984

File tree

2 files changed

+64
-24
lines changed

2 files changed

+64
-24
lines changed

src/cargo/ops/tree/graph.rs

Lines changed: 61 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@ pub enum Node {
2626
},
2727
}
2828

29+
#[derive(Debug, Copy, Hash, Eq, Clone, PartialEq)]
30+
pub struct Edge {
31+
kind: EdgeKind,
32+
node: usize,
33+
}
34+
35+
impl Edge {
36+
pub fn kind(&self) -> EdgeKind {
37+
self.kind
38+
}
39+
40+
pub fn node(&self) -> usize {
41+
self.node
42+
}
43+
}
44+
2945
/// The kind of edge, for separating dependencies into different sections.
3046
#[derive(Debug, Copy, Hash, Eq, Clone, PartialEq)]
3147
pub enum EdgeKind {
@@ -42,18 +58,18 @@ pub enum EdgeKind {
4258
/// The value is a `Vec` because each edge kind can have multiple outgoing
4359
/// edges. For example, package "foo" can have multiple normal dependencies.
4460
#[derive(Clone)]
45-
struct Edges(HashMap<EdgeKind, Vec<usize>>);
61+
struct Edges(HashMap<EdgeKind, Vec<Edge>>);
4662

4763
impl Edges {
4864
fn new() -> Edges {
4965
Edges(HashMap::new())
5066
}
5167

5268
/// Adds an edge pointing to the given node.
53-
fn add_edge(&mut self, kind: EdgeKind, index: usize) {
54-
let indexes = self.0.entry(kind).or_default();
55-
if !indexes.contains(&index) {
56-
indexes.push(index)
69+
fn add_edge(&mut self, edge: Edge) {
70+
let indexes = self.0.entry(edge.kind()).or_default();
71+
if !indexes.contains(&edge) {
72+
indexes.push(edge)
5773
}
5874
}
5975
}
@@ -104,13 +120,13 @@ impl<'a> Graph<'a> {
104120
}
105121

106122
/// Returns a list of nodes the given node index points to for the given kind.
107-
pub fn connected_nodes(&self, from: usize, kind: &EdgeKind) -> Vec<usize> {
123+
pub fn edges(&self, from: usize, kind: &EdgeKind) -> Vec<Edge> {
108124
match self.edges[from].0.get(kind) {
109-
Some(indexes) => {
125+
Some(edges) => {
110126
// Created a sorted list for consistent output.
111-
let mut indexes = indexes.clone();
112-
indexes.sort_unstable_by(|a, b| self.nodes[*a].cmp(&self.nodes[*b]));
113-
indexes
127+
let mut edges = edges.clone();
128+
edges.sort_unstable_by(|a, b| self.nodes[a.node].cmp(&self.nodes[b.node]));
129+
edges
114130
}
115131
None => Vec::new(),
116132
}
@@ -184,10 +200,14 @@ impl<'a> Graph<'a> {
184200
let new_from = new_graph.add_node(node);
185201
remap[index] = Some(new_from);
186202
// Visit dependencies.
187-
for (edge_kind, edge_indexes) in &graph.edges[index].0 {
188-
for edge_index in edge_indexes {
189-
let new_to_index = visit(graph, new_graph, remap, *edge_index);
190-
new_graph.edges[new_from].add_edge(*edge_kind, new_to_index);
203+
for (_, edges) in &graph.edges[index].0 {
204+
for edge in edges {
205+
let new_to_index = visit(graph, new_graph, remap, edge.node());
206+
let new_edge = Edge {
207+
kind: edge.kind(),
208+
node: new_to_index,
209+
};
210+
new_graph.edges[new_from].add_edge(new_edge);
191211
}
192212
}
193213
new_from
@@ -205,9 +225,13 @@ impl<'a> Graph<'a> {
205225
pub fn invert(&mut self) {
206226
let mut new_edges = vec![Edges::new(); self.edges.len()];
207227
for (from_idx, node_edges) in self.edges.iter().enumerate() {
208-
for (edge_kind, edge_indexes) in &node_edges.0 {
209-
for edge_index in edge_indexes {
210-
new_edges[*edge_index].add_edge(*edge_kind, from_idx);
228+
for (_, edges) in &node_edges.0 {
229+
for edge in edges {
230+
let new_edge = Edge {
231+
kind: edge.kind(),
232+
node: from_idx,
233+
};
234+
new_edges[edge.node()].add_edge(new_edge);
211235
}
212236
}
213237
}
@@ -454,10 +478,18 @@ fn add_pkg(
454478
}
455479
if !dep.uses_default_features() && dep.features().is_empty() {
456480
// No features, use a direct connection.
457-
graph.edges[from_index].add_edge(EdgeKind::Dep(dep.kind()), dep_index);
481+
let new_edge = Edge {
482+
kind: EdgeKind::Dep(dep.kind()),
483+
node: dep_index,
484+
};
485+
graph.edges[from_index].add_edge(new_edge);
458486
}
459487
} else {
460-
graph.edges[from_index].add_edge(EdgeKind::Dep(dep.kind()), dep_index);
488+
let new_edge = Edge {
489+
kind: EdgeKind::Dep(dep.kind()),
490+
node: dep_index,
491+
};
492+
graph.edges[from_index].add_edge(new_edge);
461493
}
462494
}
463495
}
@@ -500,9 +532,17 @@ fn add_feature(
500532
None => (true, graph.add_node(node)),
501533
};
502534
if let Some(from) = from {
503-
graph.edges[from].add_edge(kind, node_index);
535+
let from_edge = Edge {
536+
kind,
537+
node: node_index,
538+
};
539+
graph.edges[from].add_edge(from_edge);
504540
}
505-
graph.edges[node_index].add_edge(EdgeKind::Feature, to);
541+
let to_edge = Edge {
542+
kind: EdgeKind::Feature,
543+
node: to,
544+
};
545+
graph.edges[node_index].add_edge(to_edge);
506546
(missing, node_index)
507547
}
508548

src/cargo/ops/tree/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ fn print_dependencies<'a>(
383383
print_stack: &mut Vec<usize>,
384384
kind: &EdgeKind,
385385
) {
386-
let deps = graph.connected_nodes(node_index, kind);
386+
let deps = graph.edges(node_index, kind);
387387
if deps.is_empty() {
388388
return;
389389
}
@@ -420,7 +420,7 @@ fn print_dependencies<'a>(
420420
.iter()
421421
.filter(|dep| {
422422
// Filter out packages to prune.
423-
match graph.node(**dep) {
423+
match graph.node(dep.node()) {
424424
Node::Package { package_id, .. } => {
425425
if filter_non_workspace_member && !ws.is_member_id(*package_id) {
426426
return false;
@@ -437,7 +437,7 @@ fn print_dependencies<'a>(
437437
print_node(
438438
ws,
439439
graph,
440-
*dependency,
440+
dependency.node(),
441441
format,
442442
symbols,
443443
pkgs_to_prune,

0 commit comments

Comments
 (0)