@@ -27,21 +27,31 @@ pub enum Node {
27
27
} ,
28
28
}
29
29
30
+ /// The kind of edge, for separating dependencies into different sections.
30
31
#[ derive( Debug , Copy , Hash , Eq , Clone , PartialEq ) ]
31
- pub enum Edge {
32
+ pub enum EdgeKind {
32
33
Dep ( DepKind ) ,
33
34
Feature ,
34
35
}
35
36
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.
36
45
#[ derive( Clone ) ]
37
- struct Edges ( HashMap < Edge , Vec < usize > > ) ;
46
+ struct Edges ( HashMap < EdgeKind , Vec < usize > > ) ;
38
47
39
48
impl Edges {
40
49
fn new ( ) -> Edges {
41
50
Edges ( HashMap :: new ( ) )
42
51
}
43
52
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 ) {
45
55
let indexes = self . 0 . entry ( kind) . or_default ( ) ;
46
56
if !indexes. contains ( & index) {
47
57
indexes. push ( index)
@@ -52,6 +62,9 @@ impl Edges {
52
62
/// A graph of dependencies.
53
63
pub struct Graph < ' a > {
54
64
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.
55
68
edges : Vec < Edges > ,
56
69
/// Index maps a node to an index, for fast lookup.
57
70
index : HashMap < Node , usize > ,
@@ -92,7 +105,7 @@ impl<'a> Graph<'a> {
92
105
}
93
106
94
107
/// 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 > {
96
109
match self . edges [ from] . 0 . get ( kind) {
97
110
Some ( indexes) => {
98
111
// Created a sorted list for consistent output.
@@ -358,7 +371,7 @@ fn add_pkg(
358
371
InternedString :: new ( "default" ) ,
359
372
Some ( from_index) ,
360
373
dep_index,
361
- Edge :: Dep ( dep. kind ( ) ) ,
374
+ EdgeKind :: Dep ( dep. kind ( ) ) ,
362
375
) ;
363
376
}
364
377
for feature in dep. features ( ) {
@@ -367,15 +380,15 @@ fn add_pkg(
367
380
* feature,
368
381
Some ( from_index) ,
369
382
dep_index,
370
- Edge :: Dep ( dep. kind ( ) ) ,
383
+ EdgeKind :: Dep ( dep. kind ( ) ) ,
371
384
) ;
372
385
}
373
386
if !dep. uses_default_features ( ) && dep. features ( ) . is_empty ( ) {
374
387
// 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) ;
376
389
}
377
390
} 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) ;
379
392
}
380
393
}
381
394
}
@@ -401,7 +414,7 @@ fn add_feature(
401
414
name : InternedString ,
402
415
from : Option < usize > ,
403
416
to : usize ,
404
- kind : Edge ,
417
+ kind : EdgeKind ,
405
418
) -> usize {
406
419
// `to` *must* point to a package node.
407
420
assert ! ( matches! { graph. nodes[ to] , Node :: Package { ..} } ) ;
@@ -416,7 +429,7 @@ fn add_feature(
416
429
if let Some ( from) = from {
417
430
graph. edges [ from] . add_edge ( kind, node_index) ;
418
431
}
419
- graph. edges [ node_index] . add_edge ( Edge :: Feature , to) ;
432
+ graph. edges [ node_index] . add_edge ( EdgeKind :: Feature , to) ;
420
433
node_index
421
434
}
422
435
@@ -460,14 +473,15 @@ fn add_cli_features(
460
473
for ( dep_index, is_optional) in graph. dep_name_map [ & package_index] [ & dep_name] . clone ( ) {
461
474
if is_optional {
462
475
// 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 ) ;
464
478
graph. cli_features . insert ( index) ;
465
479
}
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 ) ;
467
481
graph. cli_features . insert ( index) ;
468
482
}
469
483
} 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 ) ;
471
485
graph. cli_features . insert ( index) ;
472
486
}
473
487
}
@@ -522,8 +536,13 @@ fn add_feature_rec(
522
536
for fv in fvs {
523
537
match fv {
524
538
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
+ ) ;
527
546
add_feature_rec (
528
547
graph,
529
548
resolve,
@@ -552,10 +571,16 @@ fn add_feature_rec(
552
571
let dep_pkg_id = graph. package_id_for_index ( dep_index) ;
553
572
if is_optional {
554
573
// 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
+ ) ;
556
581
}
557
582
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 ) ;
559
584
add_feature_rec ( graph, resolve, * fv_name, dep_pkg_id, feat_index, dep_index) ;
560
585
}
561
586
}
0 commit comments