1use std::borrow::Borrow;
2use std::collections::BTreeSet;
3use std::fmt;
4
5pub struct Graph<N: Clone, E: Clone> {
6 nodes: im_rc::OrdMap<N, im_rc::OrdMap<N, E>>,
7}
8
9impl<N: Eq + Ord + Clone, E: Default + Clone> Graph<N, E> {
10 pub fn new() -> Graph<N, E> {
11 Graph {
12 nodes: im_rc::OrdMap::new(),
13 }
14 }
15
16 pub fn add(&mut self, node: N) {
17 self.nodes.entry(node).or_insert_with(im_rc::OrdMap::new);
18 }
19
20 pub fn link(&mut self, node: N, child: N) -> &mut E {
21 self.nodes
22 .entry(node)
23 .or_insert_with(im_rc::OrdMap::new)
24 .entry(child)
25 .or_insert_with(Default::default)
26 }
27
28 pub fn contains<Q: ?Sized>(&self, k: &Q) -> bool
29 where
30 N: Borrow<Q>,
31 Q: Ord + Eq,
32 {
33 self.nodes.contains_key(k)
34 }
35
36 pub fn edge(&self, from: &N, to: &N) -> Option<&E> {
37 self.nodes.get(from)?.get(to)
38 }
39
40 pub fn edges(&self, from: &N) -> impl Iterator<Item = &(N, E)> {
41 self.nodes.get(from).into_iter().flat_map(|x| x.iter())
42 }
43
44 pub fn sort(&self) -> Vec<N> {
46 let mut ret = Vec::new();
47 let mut marks = BTreeSet::new();
48
49 for node in self.nodes.keys() {
50 self.sort_inner_visit(node, &mut ret, &mut marks);
51 }
52
53 ret
54 }
55
56 fn sort_inner_visit(&self, node: &N, dst: &mut Vec<N>, marks: &mut BTreeSet<N>) {
57 if !marks.insert(node.clone()) {
58 return;
59 }
60
61 for child in self.nodes[node].keys() {
62 self.sort_inner_visit(child, dst, marks);
63 }
64
65 dst.push(node.clone());
66 }
67
68 pub fn iter(&self) -> impl Iterator<Item = &N> {
69 self.nodes.keys()
70 }
71
72 pub fn is_path_from_to<'a>(&'a self, from: &'a N, to: &'a N) -> bool {
74 let mut stack = vec![from];
75 let mut seen = BTreeSet::new();
76 seen.insert(from);
77 while let Some(iter) = stack.pop().and_then(|p| self.nodes.get(p)) {
78 for p in iter.keys() {
79 if p == to {
80 return true;
81 }
82 if seen.insert(p) {
83 stack.push(p);
84 }
85 }
86 }
87 false
88 }
89
90 pub fn path_to_bottom<'a>(&'a self, mut pkg: &'a N) -> Vec<&'a N> {
93 let mut result = vec![pkg];
94 while let Some(p) = self.nodes.get(pkg).and_then(|p| {
95 p.iter()
96 .find(|&(node, _)| !result.contains(&node))
99 .map(|(ref p, _)| p)
100 }) {
101 result.push(p);
102 pkg = p;
103 }
104 result
105 }
106
107 pub fn path_to_top<'a>(&'a self, mut pkg: &'a N) -> Vec<&'a N> {
110 let mut result = vec![pkg];
114 let first_pkg_depending_on = |pkg: &N, res: &[&N]| {
115 self.nodes
116 .iter()
117 .filter(|&(_, adjacent)| adjacent.contains_key(pkg))
118 .find(|&(node, _)| !res.contains(&node))
121 .map(|(ref p, _)| p)
122 };
123 while let Some(p) = first_pkg_depending_on(pkg, &result) {
124 result.push(p);
125 pkg = p;
126 }
127 result
128 }
129}
130
131impl<N: Eq + Ord + Clone, E: Default + Clone> Default for Graph<N, E> {
132 fn default() -> Graph<N, E> {
133 Graph::new()
134 }
135}
136
137impl<N: fmt::Display + Eq + Ord + Clone, E: Clone> fmt::Debug for Graph<N, E> {
138 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
139 writeln!(fmt, "Graph {{")?;
140
141 for (n, e) in &self.nodes {
142 writeln!(fmt, " - {}", n)?;
143
144 for n in e.keys() {
145 writeln!(fmt, " - {}", n)?;
146 }
147 }
148
149 write!(fmt, "}}")?;
150
151 Ok(())
152 }
153}
154
155impl<N: Eq + Ord + Clone, E: Eq + Clone> PartialEq for Graph<N, E> {
156 fn eq(&self, other: &Graph<N, E>) -> bool {
157 self.nodes.eq(&other.nodes)
158 }
159}
160impl<N: Eq + Ord + Clone, E: Eq + Clone> Eq for Graph<N, E> {}
161
162impl<N: Eq + Ord + Clone, E: Clone> Clone for Graph<N, E> {
163 fn clone(&self) -> Graph<N, E> {
164 Graph {
165 nodes: self.nodes.clone(),
166 }
167 }
168}