1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use std::cmp::PartialEq;
use std::collections::HashSet;
use std::fmt;
use std::hash::Hash;

/// Single node in a dependency graph, which might have dependencies or be
/// be used as a dependency by other nodes.
///
/// A node is represented by a unique identifier and may contain a list of
/// dependencies.
#[derive(Clone, Debug)]
pub struct Node<I>
where
    I: Clone + fmt::Debug + Eq + Hash + PartialEq + Send + Sync,
{
    id: I,
    deps: HashSet<I>,
}

impl<I> Node<I>
where
    I: Clone + fmt::Debug + Eq + Hash + PartialEq + Send + Sync,
{
    pub fn new(id: I) -> Node<I> {
        Node {
            id,
            deps: HashSet::default(),
        }
    }

    pub fn id(&self) -> &I {
        &self.id
    }
    pub fn deps(&self) -> &HashSet<I> {
        &self.deps
    }
    pub fn add_dep(&mut self, dep: I) {
        self.deps.insert(dep);
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn empty_node() {
        let node = Node::new("node");

        assert_eq!(*node.id(), "node");
        assert_eq!(node.deps().len(), 0);
    }

    #[test]
    fn one_dep() {
        let mut root = Node::new("root");
        let dep1 = Node::new("dep1");

        root.add_dep(dep1.id());

        assert_eq!(root.deps().len(), 1);
    }

    #[test]
    fn two_deps() {
        let mut root = Node::new("root");
        let dep1 = Node::new("dep1");
        let dep2 = Node::new("dep2");

        root.add_dep(dep1.id());
        root.add_dep(dep2.id());

        assert_eq!(root.deps().len(), 2);
        assert_eq!(dep1.deps().len(), 0);
        assert_eq!(dep2.deps().len(), 0);
    }

    #[test]
    fn diamonds() {
        let mut root = Node::new("root");
        let mut dep1 = Node::new("dep1");
        let mut dep2 = Node::new("dep2");
        let leaf = Node::new("leaf");

        root.add_dep(dep1.id());
        root.add_dep(dep2.id());
        dep1.add_dep(leaf.id());
        dep2.add_dep(leaf.id());

        assert_eq!(root.deps().len(), 2);
        assert_eq!(dep1.deps().len(), 1);
        assert_eq!(dep2.deps().len(), 1);
        assert_eq!(leaf.deps().len(), 0);
    }
}