1 //! Graph traits for associated data and graph construction.
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}
;
13 /// Access node and edge weights (associated data).
14 pub trait DataMap
: Data
{
16 fn node_weight(self: &Self, id
: Self::NodeId
) -> Option
<&Self::NodeWeight
>;
17 fn edge_weight(self: &Self, id
: Self::EdgeId
) -> Option
<&Self::EdgeWeight
>;
21 macro_rules
! access0
{
27 DataMap
! {delegate_impl []}
28 DataMap
! {delegate_impl [['a, G], G, &'a mut G, deref_twice]}
29 DataMap
! {delegate_impl [[G], G, Reversed<G>, access0]}
32 /// Access node and edge weights mutably.
33 pub trait DataMapMut
: DataMap
{
35 fn node_weight_mut(self: &mut Self, id
: Self::NodeId
) -> Option
<&mut Self::NodeWeight
>;
36 fn edge_weight_mut(self: &mut Self, id
: Self::EdgeId
) -> Option
<&mut Self::EdgeWeight
>;
40 DataMapMut
! {delegate_impl [['a, G], G, &'a mut G, deref_twice]}
41 DataMapMut
! {delegate_impl [[G], G, Reversed<G>, access0]}
43 /// A graph that can be extended with further nodes and edges
44 pub trait Build
: Data
+ NodeCount
{
45 fn add_node(&mut self, weight
: Self::NodeWeight
) -> Self::NodeId
;
46 /// Add a new edge. If parallel edges (duplicate) are not allowed and
47 /// the edge already exists, return `None`.
52 weight
: Self::EdgeWeight
,
53 ) -> Option
<Self::EdgeId
> {
54 Some(self.update_edge(a
, b
, weight
))
56 /// Add or update the edge from `a` to `b`. Return the id of the affected
62 weight
: Self::EdgeWeight
,
66 /// A graph that can be created
67 pub trait Create
: Build
+ Default
{
68 fn with_capacity(nodes
: usize, edges
: usize) -> Self;
71 impl<N
, E
, Ty
, Ix
> Data
for Graph
<N
, E
, Ty
, Ix
>
79 impl<N
, E
, Ty
, Ix
> DataMap
for Graph
<N
, E
, Ty
, Ix
>
84 fn node_weight(&self, id
: Self::NodeId
) -> Option
<&Self::NodeWeight
> {
87 fn edge_weight(&self, id
: Self::EdgeId
) -> Option
<&Self::EdgeWeight
> {
92 impl<N
, E
, Ty
, Ix
> DataMapMut
for Graph
<N
, E
, Ty
, Ix
>
97 fn node_weight_mut(&mut self, id
: Self::NodeId
) -> Option
<&mut Self::NodeWeight
> {
98 self.node_weight_mut(id
)
100 fn edge_weight_mut(&mut self, id
: Self::EdgeId
) -> Option
<&mut Self::EdgeWeight
> {
101 self.edge_weight_mut(id
)
105 #[cfg(feature = "stable_graph")]
106 impl<N
, E
, Ty
, Ix
> DataMap
for StableGraph
<N
, E
, Ty
, Ix
>
111 fn node_weight(&self, id
: Self::NodeId
) -> Option
<&Self::NodeWeight
> {
114 fn edge_weight(&self, id
: Self::EdgeId
) -> Option
<&Self::EdgeWeight
> {
119 #[cfg(feature = "stable_graph")]
120 impl<N
, E
, Ty
, Ix
> DataMapMut
for StableGraph
<N
, E
, Ty
, Ix
>
125 fn node_weight_mut(&mut self, id
: Self::NodeId
) -> Option
<&mut Self::NodeWeight
> {
126 self.node_weight_mut(id
)
128 fn edge_weight_mut(&mut self, id
: Self::EdgeId
) -> Option
<&mut Self::EdgeWeight
> {
129 self.edge_weight_mut(id
)
133 impl<N
, E
, Ty
, Ix
> Build
for Graph
<N
, E
, Ty
, Ix
>
138 fn add_node(&mut self, weight
: Self::NodeWeight
) -> Self::NodeId
{
139 self.add_node(weight
)
145 weight
: Self::EdgeWeight
,
146 ) -> Option
<Self::EdgeId
> {
147 Some(self.add_edge(a
, b
, weight
))
153 weight
: Self::EdgeWeight
,
155 self.update_edge(a
, b
, weight
)
159 #[cfg(feature = "stable_graph")]
160 impl<N
, E
, Ty
, Ix
> Build
for StableGraph
<N
, E
, Ty
, Ix
>
165 fn add_node(&mut self, weight
: Self::NodeWeight
) -> Self::NodeId
{
166 self.add_node(weight
)
172 weight
: Self::EdgeWeight
,
173 ) -> Option
<Self::EdgeId
> {
174 Some(self.add_edge(a
, b
, weight
))
180 weight
: Self::EdgeWeight
,
182 self.update_edge(a
, b
, weight
)
186 #[cfg(feature = "graphmap")]
187 impl<N
, E
, Ty
> Build
for GraphMap
<N
, E
, Ty
>
192 fn add_node(&mut self, weight
: Self::NodeWeight
) -> Self::NodeId
{
193 self.add_node(weight
)
199 weight
: Self::EdgeWeight
,
200 ) -> Option
<Self::EdgeId
> {
201 if self.contains_edge(a
, b
) {
204 let r
= self.add_edge(a
, b
, weight
);
205 debug_assert
!(r
.is_none());
213 weight
: Self::EdgeWeight
,
215 self.add_edge(a
, b
, weight
);
220 impl<N
, E
, Ty
, Ix
> Create
for Graph
<N
, E
, Ty
, Ix
>
225 fn with_capacity(nodes
: usize, edges
: usize) -> Self {
226 Self::with_capacity(nodes
, edges
)
230 #[cfg(feature = "stable_graph")]
231 impl<N
, E
, Ty
, Ix
> Create
for StableGraph
<N
, E
, Ty
, Ix
>
236 fn with_capacity(nodes
: usize, edges
: usize) -> Self {
237 Self::with_capacity(nodes
, edges
)
241 #[cfg(feature = "graphmap")]
242 impl<N
, E
, Ty
> Create
for GraphMap
<N
, E
, Ty
>
247 fn with_capacity(nodes
: usize, edges
: usize) -> Self {
248 Self::with_capacity(nodes
, edges
)
254 /// A sequence of Elements, for example an iterator, is laid out as follows:
255 /// Nodes are implicitly given the index of their appearance in the sequence.
256 /// The edges’ source and target fields refer to these indices.
257 #[derive(Clone, Debug, PartialEq, Eq)]
258 pub enum Element
<N
, E
> {
269 /// Create a graph from an iterator of elements.
270 pub trait FromElements
: Create
{
271 fn from_elements
<I
>(iterable
: I
) -> Self
274 I
: IntoIterator
<Item
= Element
<Self::NodeWeight
, Self::EdgeWeight
>>,
276 let mut gr
= Self::with_capacity(0, 0);
277 // usize -> NodeId map
278 let mut map
= Vec
::new();
279 for element
in iterable
{
281 Element
::Node { weight }
=> {
282 map
.push(gr
.add_node(weight
));
289 gr
.add_edge(map
[source
], map
[target
], weight
);
297 fn from_elements_indexable
<G
, I
>(iterable
: I
) -> G
299 G
: Create
+ NodeIndexable
,
300 I
: IntoIterator
<Item
= Element
<G
::NodeWeight
, G
::EdgeWeight
>>,
302 let mut gr
= G
::with_capacity(0, 0);
303 let map
= |gr
: &G
, i
| gr
.from_index(i
);
304 for element
in iterable
{
306 Element
::Node { weight }
=> {
314 let from
= map(&gr
, source
);
315 let to
= map(&gr
, target
);
316 gr
.add_edge(from
, to
, weight
);
323 impl<N
, E
, Ty
, Ix
> FromElements
for Graph
<N
, E
, Ty
, Ix
>
328 fn from_elements
<I
>(iterable
: I
) -> Self
331 I
: IntoIterator
<Item
= Element
<Self::NodeWeight
, Self::EdgeWeight
>>,
333 from_elements_indexable(iterable
)
337 #[cfg(feature = "stable_graph")]
338 impl<N
, E
, Ty
, Ix
> FromElements
for StableGraph
<N
, E
, Ty
, Ix
>
343 fn from_elements
<I
>(iterable
: I
) -> Self
346 I
: IntoIterator
<Item
= Element
<Self::NodeWeight
, Self::EdgeWeight
>>,
348 from_elements_indexable(iterable
)
352 #[cfg(feature = "graphmap")]
353 impl<N
, E
, Ty
> FromElements
for GraphMap
<N
, E
, Ty
>
358 fn from_elements
<I
>(iterable
: I
) -> Self
361 I
: IntoIterator
<Item
= Element
<Self::NodeWeight
, Self::EdgeWeight
>>,
363 from_elements_indexable(iterable
)
367 /// Iterator adaptors for iterators of `Element`.
368 pub trait ElementIterator
<N
, E
>: Iterator
<Item
= Element
<N
, E
>> {
369 /// Create an iterator adaptor that filters graph elements.
371 /// The function `f` is called with each element and if its return value
372 /// is `true` the element is accepted and if `false` it is removed.
373 /// `f` is called with mutable references to the node and edge weights,
374 /// so that they can be mutated (but the edge endpoints can not).
376 /// This filter adapts the edge source and target indices in the
377 /// stream so that they are correct after the removals.
378 fn filter_elements
<F
>(self, f
: F
) -> FilterElements
<Self, F
>
381 F
: FnMut(Element
<&mut N
, &mut E
>) -> bool
,
392 impl<N
, E
, I
: ?Sized
> ElementIterator
<N
, E
> for I
where I
: Iterator
<Item
= Element
<N
, E
>> {}
394 /// An iterator that filters graph elements.
396 /// See [`.filter_elements()`][1] for more information.
398 /// [1]: trait.ElementIterator.html#method.filter_elements
399 pub struct FilterElements
<I
, F
> {
406 impl<I
, F
, N
, E
> Iterator
for FilterElements
<I
, F
>
408 I
: Iterator
<Item
= Element
<N
, E
>>,
409 F
: FnMut(Element
<&mut N
, &mut E
>) -> bool
,
411 type Item
= Element
<N
, E
>;
413 fn next(&mut self) -> Option
<Self::Item
> {
415 let mut elt
= match self.iter
.next() {
419 let keep
= (self.f
)(match elt
{
420 Element
::Node { ref mut weight }
=> Element
::Node { weight }
,
431 let is_node
= if let Element
::Node { .. }
= elt
{
436 if !keep
&& is_node
{
437 self.map
.push(self.node_index
);
440 self.node_index
+= 1;
453 // Find the node indices in the map of removed ones.
454 // If a node was removed, the edge is as well.
455 // Otherwise the counts are adjusted by the number of nodes
457 // Example: map: [1, 3, 4, 6]
458 // binary search for 2, result is Err(1). One node has been
460 match self.map
.binary_search(source
) {
462 Err(i
) => *source
-= i
,
464 match self.map
.binary_search(target
) {
466 Err(i
) => *target
-= i
,
469 Element
::Node { .. }
=> {}