1 //! Graph traits for associated data and graph construction.
2
3 use crate::graph::IndexType;
4 #[cfg(feature = "graphmap")]
5 use crate::graphmap::{GraphMap, NodeTrait};
6 #[cfg(feature = "stable_graph")]
7 use crate::stable_graph::StableGraph;
8 use crate::visit::{Data, NodeCount, NodeIndexable, Reversed};
9 use crate::EdgeType;
10 use crate::Graph;
11
12 trait_template! {
13 /// Access node and edge weights (associated data).
14 #[allow(clippy::needless_arbitrary_self_type)]
15 pub trait DataMap : Data {
16 @section self
17 fn node_weight(self: &Self, id: Self::NodeId) -> Option<&Self::NodeWeight>;
18 fn edge_weight(self: &Self, id: Self::EdgeId) -> Option<&Self::EdgeWeight>;
19 }
20 }
21
22 macro_rules! access0 {
23 ($e:expr) => {
24 $e.0
25 };
26 }
27
28 DataMap! {delegate_impl []}
29 DataMap! {delegate_impl [['a, G], G, &'a mut G, deref_twice]}
30 DataMap! {delegate_impl [[G], G, Reversed<G>, access0]}
31
32 trait_template! {
33 /// Access node and edge weights mutably.
34 #[allow(clippy::needless_arbitrary_self_type)]
35 pub trait DataMapMut : DataMap {
36 @section self
37 fn node_weight_mut(self: &mut Self, id: Self::NodeId) -> Option<&mut Self::NodeWeight>;
38 fn edge_weight_mut(self: &mut Self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight>;
39 }
40 }
41
42 DataMapMut! {delegate_impl [['a, G], G, &'a mut G, deref_twice]}
43 DataMapMut! {delegate_impl [[G], G, Reversed<G>, access0]}
44
45 /// A graph that can be extended with further nodes and edges
46 pub trait Build: Data + NodeCount {
add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId47 fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId;
48 /// Add a new edge. If parallel edges (duplicate) are not allowed and
49 /// the edge already exists, return `None`.
add_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Option<Self::EdgeId>50 fn add_edge(
51 &mut self,
52 a: Self::NodeId,
53 b: Self::NodeId,
54 weight: Self::EdgeWeight,
55 ) -> Option<Self::EdgeId> {
56 Some(self.update_edge(a, b, weight))
57 }
58 /// Add or update the edge from `a` to `b`. Return the id of the affected
59 /// edge.
update_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Self::EdgeId60 fn update_edge(
61 &mut self,
62 a: Self::NodeId,
63 b: Self::NodeId,
64 weight: Self::EdgeWeight,
65 ) -> Self::EdgeId;
66 }
67
68 /// A graph that can be created
69 pub trait Create: Build + Default {
with_capacity(nodes: usize, edges: usize) -> Self70 fn with_capacity(nodes: usize, edges: usize) -> Self;
71 }
72
73 impl<N, E, Ty, Ix> Data for Graph<N, E, Ty, Ix>
74 where
75 Ix: IndexType,
76 {
77 type NodeWeight = N;
78 type EdgeWeight = E;
79 }
80
81 impl<N, E, Ty, Ix> DataMap for Graph<N, E, Ty, Ix>
82 where
83 Ty: EdgeType,
84 Ix: IndexType,
85 {
node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight>86 fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
87 self.node_weight(id)
88 }
edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight>89 fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
90 self.edge_weight(id)
91 }
92 }
93
94 impl<N, E, Ty, Ix> DataMapMut for Graph<N, E, Ty, Ix>
95 where
96 Ty: EdgeType,
97 Ix: IndexType,
98 {
node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight>99 fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
100 self.node_weight_mut(id)
101 }
edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight>102 fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
103 self.edge_weight_mut(id)
104 }
105 }
106
107 #[cfg(feature = "stable_graph")]
108 impl<N, E, Ty, Ix> DataMap for StableGraph<N, E, Ty, Ix>
109 where
110 Ty: EdgeType,
111 Ix: IndexType,
112 {
node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight>113 fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
114 self.node_weight(id)
115 }
edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight>116 fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
117 self.edge_weight(id)
118 }
119 }
120
121 #[cfg(feature = "stable_graph")]
122 impl<N, E, Ty, Ix> DataMapMut for StableGraph<N, E, Ty, Ix>
123 where
124 Ty: EdgeType,
125 Ix: IndexType,
126 {
node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight>127 fn node_weight_mut(&mut self, id: Self::NodeId) -> Option<&mut Self::NodeWeight> {
128 self.node_weight_mut(id)
129 }
edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight>130 fn edge_weight_mut(&mut self, id: Self::EdgeId) -> Option<&mut Self::EdgeWeight> {
131 self.edge_weight_mut(id)
132 }
133 }
134
135 impl<N, E, Ty, Ix> Build for Graph<N, E, Ty, Ix>
136 where
137 Ty: EdgeType,
138 Ix: IndexType,
139 {
add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId140 fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
141 self.add_node(weight)
142 }
add_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Option<Self::EdgeId>143 fn add_edge(
144 &mut self,
145 a: Self::NodeId,
146 b: Self::NodeId,
147 weight: Self::EdgeWeight,
148 ) -> Option<Self::EdgeId> {
149 Some(self.add_edge(a, b, weight))
150 }
update_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Self::EdgeId151 fn update_edge(
152 &mut self,
153 a: Self::NodeId,
154 b: Self::NodeId,
155 weight: Self::EdgeWeight,
156 ) -> Self::EdgeId {
157 self.update_edge(a, b, weight)
158 }
159 }
160
161 #[cfg(feature = "stable_graph")]
162 impl<N, E, Ty, Ix> Build for StableGraph<N, E, Ty, Ix>
163 where
164 Ty: EdgeType,
165 Ix: IndexType,
166 {
add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId167 fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
168 self.add_node(weight)
169 }
add_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Option<Self::EdgeId>170 fn add_edge(
171 &mut self,
172 a: Self::NodeId,
173 b: Self::NodeId,
174 weight: Self::EdgeWeight,
175 ) -> Option<Self::EdgeId> {
176 Some(self.add_edge(a, b, weight))
177 }
update_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Self::EdgeId178 fn update_edge(
179 &mut self,
180 a: Self::NodeId,
181 b: Self::NodeId,
182 weight: Self::EdgeWeight,
183 ) -> Self::EdgeId {
184 self.update_edge(a, b, weight)
185 }
186 }
187
188 #[cfg(feature = "graphmap")]
189 impl<N, E, Ty> Build for GraphMap<N, E, Ty>
190 where
191 Ty: EdgeType,
192 N: NodeTrait,
193 {
add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId194 fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
195 self.add_node(weight)
196 }
add_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Option<Self::EdgeId>197 fn add_edge(
198 &mut self,
199 a: Self::NodeId,
200 b: Self::NodeId,
201 weight: Self::EdgeWeight,
202 ) -> Option<Self::EdgeId> {
203 if self.contains_edge(a, b) {
204 None
205 } else {
206 let r = self.add_edge(a, b, weight);
207 debug_assert!(r.is_none());
208 Some((a, b))
209 }
210 }
update_edge( &mut self, a: Self::NodeId, b: Self::NodeId, weight: Self::EdgeWeight, ) -> Self::EdgeId211 fn update_edge(
212 &mut self,
213 a: Self::NodeId,
214 b: Self::NodeId,
215 weight: Self::EdgeWeight,
216 ) -> Self::EdgeId {
217 self.add_edge(a, b, weight);
218 (a, b)
219 }
220 }
221
222 impl<N, E, Ty, Ix> Create for Graph<N, E, Ty, Ix>
223 where
224 Ty: EdgeType,
225 Ix: IndexType,
226 {
with_capacity(nodes: usize, edges: usize) -> Self227 fn with_capacity(nodes: usize, edges: usize) -> Self {
228 Self::with_capacity(nodes, edges)
229 }
230 }
231
232 #[cfg(feature = "stable_graph")]
233 impl<N, E, Ty, Ix> Create for StableGraph<N, E, Ty, Ix>
234 where
235 Ty: EdgeType,
236 Ix: IndexType,
237 {
with_capacity(nodes: usize, edges: usize) -> Self238 fn with_capacity(nodes: usize, edges: usize) -> Self {
239 Self::with_capacity(nodes, edges)
240 }
241 }
242
243 #[cfg(feature = "graphmap")]
244 impl<N, E, Ty> Create for GraphMap<N, E, Ty>
245 where
246 Ty: EdgeType,
247 N: NodeTrait,
248 {
with_capacity(nodes: usize, edges: usize) -> Self249 fn with_capacity(nodes: usize, edges: usize) -> Self {
250 Self::with_capacity(nodes, edges)
251 }
252 }
253
254 /// A graph element.
255 ///
256 /// A sequence of Elements, for example an iterator, is laid out as follows:
257 /// Nodes are implicitly given the index of their appearance in the sequence.
258 /// The edges’ source and target fields refer to these indices.
259 #[derive(Clone, Debug, PartialEq, Eq)]
260 pub enum Element<N, E> {
261 /// A graph node.
262 Node { weight: N },
263 /// A graph edge.
264 Edge {
265 source: usize,
266 target: usize,
267 weight: E,
268 },
269 }
270
271 /// Create a graph from an iterator of elements.
272 pub trait FromElements: Create {
from_elements<I>(iterable: I) -> Self where Self: Sized, I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,273 fn from_elements<I>(iterable: I) -> Self
274 where
275 Self: Sized,
276 I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
277 {
278 let mut gr = Self::with_capacity(0, 0);
279 // usize -> NodeId map
280 let mut map = Vec::new();
281 for element in iterable {
282 match element {
283 Element::Node { weight } => {
284 map.push(gr.add_node(weight));
285 }
286 Element::Edge {
287 source,
288 target,
289 weight,
290 } => {
291 gr.add_edge(map[source], map[target], weight);
292 }
293 }
294 }
295 gr
296 }
297 }
298
from_elements_indexable<G, I>(iterable: I) -> G where G: Create + NodeIndexable, I: IntoIterator<Item = Element<G::NodeWeight, G::EdgeWeight>>,299 fn from_elements_indexable<G, I>(iterable: I) -> G
300 where
301 G: Create + NodeIndexable,
302 I: IntoIterator<Item = Element<G::NodeWeight, G::EdgeWeight>>,
303 {
304 let mut gr = G::with_capacity(0, 0);
305 let map = |gr: &G, i| gr.from_index(i);
306 for element in iterable {
307 match element {
308 Element::Node { weight } => {
309 gr.add_node(weight);
310 }
311 Element::Edge {
312 source,
313 target,
314 weight,
315 } => {
316 let from = map(&gr, source);
317 let to = map(&gr, target);
318 gr.add_edge(from, to, weight);
319 }
320 }
321 }
322 gr
323 }
324
325 impl<N, E, Ty, Ix> FromElements for Graph<N, E, Ty, Ix>
326 where
327 Ty: EdgeType,
328 Ix: IndexType,
329 {
from_elements<I>(iterable: I) -> Self where Self: Sized, I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,330 fn from_elements<I>(iterable: I) -> Self
331 where
332 Self: Sized,
333 I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
334 {
335 from_elements_indexable(iterable)
336 }
337 }
338
339 #[cfg(feature = "stable_graph")]
340 impl<N, E, Ty, Ix> FromElements for StableGraph<N, E, Ty, Ix>
341 where
342 Ty: EdgeType,
343 Ix: IndexType,
344 {
from_elements<I>(iterable: I) -> Self where Self: Sized, I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,345 fn from_elements<I>(iterable: I) -> Self
346 where
347 Self: Sized,
348 I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
349 {
350 from_elements_indexable(iterable)
351 }
352 }
353
354 #[cfg(feature = "graphmap")]
355 impl<N, E, Ty> FromElements for GraphMap<N, E, Ty>
356 where
357 Ty: EdgeType,
358 N: NodeTrait,
359 {
from_elements<I>(iterable: I) -> Self where Self: Sized, I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,360 fn from_elements<I>(iterable: I) -> Self
361 where
362 Self: Sized,
363 I: IntoIterator<Item = Element<Self::NodeWeight, Self::EdgeWeight>>,
364 {
365 from_elements_indexable(iterable)
366 }
367 }
368
369 /// Iterator adaptors for iterators of `Element`.
370 pub trait ElementIterator<N, E>: Iterator<Item = Element<N, E>> {
371 /// Create an iterator adaptor that filters graph elements.
372 ///
373 /// The function `f` is called with each element and if its return value
374 /// is `true` the element is accepted and if `false` it is removed.
375 /// `f` is called with mutable references to the node and edge weights,
376 /// so that they can be mutated (but the edge endpoints can not).
377 ///
378 /// This filter adapts the edge source and target indices in the
379 /// stream so that they are correct after the removals.
filter_elements<F>(self, f: F) -> FilterElements<Self, F> where Self: Sized, F: FnMut(Element<&mut N, &mut E>) -> bool,380 fn filter_elements<F>(self, f: F) -> FilterElements<Self, F>
381 where
382 Self: Sized,
383 F: FnMut(Element<&mut N, &mut E>) -> bool,
384 {
385 FilterElements {
386 iter: self,
387 node_index: 0,
388 map: Vec::new(),
389 f,
390 }
391 }
392 }
393
394 impl<N, E, I: ?Sized> ElementIterator<N, E> for I where I: Iterator<Item = Element<N, E>> {}
395
396 /// An iterator that filters graph elements.
397 ///
398 /// See [`.filter_elements()`][1] for more information.
399 ///
400 /// [1]: trait.ElementIterator.html#method.filter_elements
401 #[derive(Debug, Clone)]
402 pub struct FilterElements<I, F> {
403 iter: I,
404 node_index: usize,
405 map: Vec<usize>,
406 f: F,
407 }
408
409 impl<I, F, N, E> Iterator for FilterElements<I, F>
410 where
411 I: Iterator<Item = Element<N, E>>,
412 F: FnMut(Element<&mut N, &mut E>) -> bool,
413 {
414 type Item = Element<N, E>;
415
next(&mut self) -> Option<Self::Item>416 fn next(&mut self) -> Option<Self::Item> {
417 loop {
418 let mut elt = match self.iter.next() {
419 None => return None,
420 Some(elt) => elt,
421 };
422 let keep = (self.f)(match elt {
423 Element::Node { ref mut weight } => Element::Node { weight },
424 Element::Edge {
425 source,
426 target,
427 ref mut weight,
428 } => Element::Edge {
429 source,
430 target,
431 weight,
432 },
433 });
434 let is_node = if let Element::Node { .. } = elt {
435 true
436 } else {
437 false
438 };
439 if !keep && is_node {
440 self.map.push(self.node_index);
441 }
442 if is_node {
443 self.node_index += 1;
444 }
445 if !keep {
446 continue;
447 }
448
449 // map edge parts
450 match elt {
451 Element::Edge {
452 ref mut source,
453 ref mut target,
454 ..
455 } => {
456 // Find the node indices in the map of removed ones.
457 // If a node was removed, the edge is as well.
458 // Otherwise the counts are adjusted by the number of nodes
459 // removed.
460 // Example: map: [1, 3, 4, 6]
461 // binary search for 2, result is Err(1). One node has been
462 // removed before 2.
463 match self.map.binary_search(source) {
464 Ok(_) => continue,
465 Err(i) => *source -= i,
466 }
467 match self.map.binary_search(target) {
468 Ok(_) => continue,
469 Err(i) => *target -= i,
470 }
471 }
472 Element::Node { .. } => {}
473 }
474 return Some(elt);
475 }
476 }
size_hint(&self) -> (usize, Option<usize>)477 fn size_hint(&self) -> (usize, Option<usize>) {
478 let (_, upper) = self.iter.size_hint();
479 (0, upper)
480 }
481 }
482