Skip to content

Commit b1fd8e9

Browse files
committed
Try to clarify how node edges works.
1 parent feaa312 commit b1fd8e9

File tree

2 files changed

+52
-27
lines changed

2 files changed

+52
-27
lines changed

src/cargo/ops/tree/graph.rs

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,31 @@ pub enum Node {
2727
},
2828
}
2929

30+
/// The kind of edge, for separating dependencies into different sections.
3031
#[derive(Debug, Copy, Hash, Eq, Clone, PartialEq)]
31-
pub enum Edge {
32+
pub enum EdgeKind {
3233
Dep(DepKind),
3334
Feature,
3435
}
3536

37+
/// Set of outgoing edges for a single node.
38+
///
39+
/// Edges are separated by the edge kind (`DepKind` or `Feature`). This is
40+
/// primarily done so that the output can easily display separate sections
41+
/// like `[build-dependencies]`.
42+
///
43+
/// The value is a `Vec` because each edge kind can have multiple outgoing
44+
/// edges. For example, package "foo" can have multiple normal dependencies.
3645
#[derive(Clone)]
37-
struct Edges(HashMap<Edge, Vec<usize>>);
46+
struct Edges(HashMap<EdgeKind, Vec<usize>>);
3847

3948
impl Edges {
4049
fn new() -> Edges {
4150
Edges(HashMap::new())
4251
}
4352

44-
fn add_edge(&mut self, kind: Edge, index: usize) {
53+
/// Adds an edge pointing to the given node.
54+
fn add_edge(&mut self, kind: EdgeKind, index: usize) {
4555
let indexes = self.0.entry(kind).or_default();
4656
if !indexes.contains(&index) {
4757
indexes.push(index)
@@ -52,6 +62,9 @@ impl Edges {
5262
/// A graph of dependencies.
5363
pub struct Graph<'a> {
5464
nodes: Vec<Node>,
65+
/// The indexes of `edges` correspond to the `nodes`. That is, `edges[0]`
66+
/// is the set of outgoing edges for `nodes[0]`. They should always be in
67+
/// sync.
5568
edges: Vec<Edges>,
5669
/// Index maps a node to an index, for fast lookup.
5770
index: HashMap<Node, usize>,
@@ -92,7 +105,7 @@ impl<'a> Graph<'a> {
92105
}
93106

94107
/// Returns a list of nodes the given node index points to for the given kind.
95-
pub fn connected_nodes(&self, from: usize, kind: &Edge) -> Vec<usize> {
108+
pub fn connected_nodes(&self, from: usize, kind: &EdgeKind) -> Vec<usize> {
96109
match self.edges[from].0.get(kind) {
97110
Some(indexes) => {
98111
// Created a sorted list for consistent output.
@@ -358,7 +371,7 @@ fn add_pkg(
358371
InternedString::new("default"),
359372
Some(from_index),
360373
dep_index,
361-
Edge::Dep(dep.kind()),
374+
EdgeKind::Dep(dep.kind()),
362375
);
363376
}
364377
for feature in dep.features() {
@@ -367,15 +380,15 @@ fn add_pkg(
367380
*feature,
368381
Some(from_index),
369382
dep_index,
370-
Edge::Dep(dep.kind()),
383+
EdgeKind::Dep(dep.kind()),
371384
);
372385
}
373386
if !dep.uses_default_features() && dep.features().is_empty() {
374387
// No features, use a direct connection.
375-
graph.edges[from_index].add_edge(Edge::Dep(dep.kind()), dep_index);
388+
graph.edges[from_index].add_edge(EdgeKind::Dep(dep.kind()), dep_index);
376389
}
377390
} else {
378-
graph.edges[from_index].add_edge(Edge::Dep(dep.kind()), dep_index);
391+
graph.edges[from_index].add_edge(EdgeKind::Dep(dep.kind()), dep_index);
379392
}
380393
}
381394
}
@@ -401,7 +414,7 @@ fn add_feature(
401414
name: InternedString,
402415
from: Option<usize>,
403416
to: usize,
404-
kind: Edge,
417+
kind: EdgeKind,
405418
) -> usize {
406419
// `to` *must* point to a package node.
407420
assert!(matches! {graph.nodes[to], Node::Package{..}});
@@ -416,7 +429,7 @@ fn add_feature(
416429
if let Some(from) = from {
417430
graph.edges[from].add_edge(kind, node_index);
418431
}
419-
graph.edges[node_index].add_edge(Edge::Feature, to);
432+
graph.edges[node_index].add_edge(EdgeKind::Feature, to);
420433
node_index
421434
}
422435

@@ -460,14 +473,15 @@ fn add_cli_features(
460473
for (dep_index, is_optional) in graph.dep_name_map[&package_index][&dep_name].clone() {
461474
if is_optional {
462475
// Activate the optional dep on self.
463-
let index = add_feature(graph, dep_name, None, package_index, Edge::Feature);
476+
let index =
477+
add_feature(graph, dep_name, None, package_index, EdgeKind::Feature);
464478
graph.cli_features.insert(index);
465479
}
466-
let index = add_feature(graph, feat_name, None, dep_index, Edge::Feature);
480+
let index = add_feature(graph, feat_name, None, dep_index, EdgeKind::Feature);
467481
graph.cli_features.insert(index);
468482
}
469483
} else {
470-
let index = add_feature(graph, name, None, package_index, Edge::Feature);
484+
let index = add_feature(graph, name, None, package_index, EdgeKind::Feature);
471485
graph.cli_features.insert(index);
472486
}
473487
}
@@ -522,8 +536,13 @@ fn add_feature_rec(
522536
for fv in fvs {
523537
match fv {
524538
FeatureValue::Feature(fv_name) | FeatureValue::Crate(fv_name) => {
525-
let feat_index =
526-
add_feature(graph, *fv_name, Some(from), package_index, Edge::Feature);
539+
let feat_index = add_feature(
540+
graph,
541+
*fv_name,
542+
Some(from),
543+
package_index,
544+
EdgeKind::Feature,
545+
);
527546
add_feature_rec(
528547
graph,
529548
resolve,
@@ -552,10 +571,16 @@ fn add_feature_rec(
552571
let dep_pkg_id = graph.package_id_for_index(dep_index);
553572
if is_optional {
554573
// Activate the optional dep on self.
555-
add_feature(graph, *dep_name, Some(from), package_index, Edge::Feature);
574+
add_feature(
575+
graph,
576+
*dep_name,
577+
Some(from),
578+
package_index,
579+
EdgeKind::Feature,
580+
);
556581
}
557582
let feat_index =
558-
add_feature(graph, *fv_name, Some(from), dep_index, Edge::Feature);
583+
add_feature(graph, *fv_name, Some(from), dep_index, EdgeKind::Feature);
559584
add_feature_rec(graph, resolve, *fv_name, dep_pkg_id, feat_index, dep_index);
560585
}
561586
}

src/cargo/ops/tree/mod.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::str::FromStr;
1515
mod format;
1616
mod graph;
1717

18-
pub use {graph::Edge, graph::Node};
18+
pub use {graph::EdgeKind, graph::Node};
1919

2020
pub struct TreeOptions {
2121
pub features: Vec<String>,
@@ -257,10 +257,10 @@ fn print_node<'a>(
257257
print_stack.push(node_index);
258258

259259
for kind in &[
260-
Edge::Dep(DepKind::Normal),
261-
Edge::Dep(DepKind::Build),
262-
Edge::Dep(DepKind::Development),
263-
Edge::Feature,
260+
EdgeKind::Dep(DepKind::Normal),
261+
EdgeKind::Dep(DepKind::Build),
262+
EdgeKind::Dep(DepKind::Development),
263+
EdgeKind::Feature,
264264
] {
265265
print_dependencies(
266266
graph,
@@ -289,18 +289,18 @@ fn print_dependencies<'a>(
289289
visited_deps: &mut HashSet<usize>,
290290
levels_continue: &mut Vec<bool>,
291291
print_stack: &mut Vec<usize>,
292-
kind: &Edge,
292+
kind: &EdgeKind,
293293
) {
294294
let deps = graph.connected_nodes(node_index, kind);
295295
if deps.is_empty() {
296296
return;
297297
}
298298

299299
let name = match kind {
300-
Edge::Dep(DepKind::Normal) => None,
301-
Edge::Dep(DepKind::Build) => Some("[build-dependencies]"),
302-
Edge::Dep(DepKind::Development) => Some("[dev-dependencies]"),
303-
Edge::Feature => None,
300+
EdgeKind::Dep(DepKind::Normal) => None,
301+
EdgeKind::Dep(DepKind::Build) => Some("[build-dependencies]"),
302+
EdgeKind::Dep(DepKind::Development) => Some("[dev-dependencies]"),
303+
EdgeKind::Feature => None,
304304
};
305305

306306
if let Prefix::Indent = prefix {

0 commit comments

Comments
 (0)