petgraph/visit/
reversed.rs

1use crate::{Direction, Incoming};
2
3use crate::visit::{
4    Data, EdgeRef, GraphBase, GraphProp, GraphRef, IntoEdgeReferences, IntoEdges,
5    IntoEdgesDirected, IntoNeighbors, IntoNeighborsDirected, IntoNodeIdentifiers,
6    IntoNodeReferences, NodeCompactIndexable, NodeCount, NodeIndexable, Visitable,
7};
8
9/// An edge-reversing graph adaptor.
10///
11/// All edges have the opposite direction with `Reversed`.
12#[derive(Copy, Clone, Debug)]
13pub struct Reversed<G>(pub G);
14
15impl<G: GraphBase> GraphBase for Reversed<G> {
16    type NodeId = G::NodeId;
17    type EdgeId = G::EdgeId;
18}
19
20impl<G: GraphRef> GraphRef for Reversed<G> {}
21
22Data! {delegate_impl [[G], G, Reversed<G>, access0]}
23
24impl<G> IntoNeighbors for Reversed<G>
25where
26    G: IntoNeighborsDirected,
27{
28    type Neighbors = G::NeighborsDirected;
29    fn neighbors(self, n: G::NodeId) -> G::NeighborsDirected {
30        self.0.neighbors_directed(n, Incoming)
31    }
32}
33
34impl<G> IntoNeighborsDirected for Reversed<G>
35where
36    G: IntoNeighborsDirected,
37{
38    type NeighborsDirected = G::NeighborsDirected;
39    fn neighbors_directed(self, n: G::NodeId, d: Direction) -> G::NeighborsDirected {
40        self.0.neighbors_directed(n, d.opposite())
41    }
42}
43
44impl<G> IntoEdges for Reversed<G>
45where
46    G: IntoEdgesDirected,
47{
48    type Edges = ReversedEdges<G::EdgesDirected>;
49    fn edges(self, a: Self::NodeId) -> Self::Edges {
50        ReversedEdges {
51            iter: self.0.edges_directed(a, Incoming),
52        }
53    }
54}
55
56impl<G> IntoEdgesDirected for Reversed<G>
57where
58    G: IntoEdgesDirected,
59{
60    type EdgesDirected = ReversedEdges<G::EdgesDirected>;
61    fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::Edges {
62        ReversedEdges {
63            iter: self.0.edges_directed(a, dir.opposite()),
64        }
65    }
66}
67
68impl<G: Visitable> Visitable for Reversed<G> {
69    type Map = G::Map;
70    fn visit_map(&self) -> G::Map {
71        self.0.visit_map()
72    }
73    fn reset_map(&self, map: &mut Self::Map) {
74        self.0.reset_map(map);
75    }
76}
77
78/// A reversed edges iterator.
79pub struct ReversedEdges<I> {
80    iter: I,
81}
82
83impl<I> Iterator for ReversedEdges<I>
84where
85    I: Iterator,
86    I::Item: EdgeRef,
87{
88    type Item = ReversedEdgeReference<I::Item>;
89    fn next(&mut self) -> Option<Self::Item> {
90        self.iter.next().map(ReversedEdgeReference)
91    }
92}
93
94/// A reversed edge reference
95#[derive(Copy, Clone, Debug)]
96pub struct ReversedEdgeReference<R>(R);
97
98impl<R> ReversedEdgeReference<R> {
99    /// Return the original, unreversed edge reference.
100    pub fn as_unreversed(&self) -> &R { &self.0 }
101
102    /// Consume `self` and return the original, unreversed edge reference.
103    pub fn into_unreversed(self) -> R {
104        self.0
105    }
106}
107
108/// An edge reference
109impl<R> EdgeRef for ReversedEdgeReference<R>
110where
111    R: EdgeRef,
112{
113    type NodeId = R::NodeId;
114    type EdgeId = R::EdgeId;
115    type Weight = R::Weight;
116    fn source(&self) -> Self::NodeId {
117        self.0.target()
118    }
119    fn target(&self) -> Self::NodeId {
120        self.0.source()
121    }
122    fn weight(&self) -> &Self::Weight {
123        self.0.weight()
124    }
125    fn id(&self) -> Self::EdgeId {
126        self.0.id()
127    }
128}
129
130impl<G> IntoEdgeReferences for Reversed<G>
131where
132    G: IntoEdgeReferences,
133{
134    type EdgeRef = ReversedEdgeReference<G::EdgeRef>;
135    type EdgeReferences = ReversedEdgeReferences<G::EdgeReferences>;
136    fn edge_references(self) -> Self::EdgeReferences {
137        ReversedEdgeReferences {
138            iter: self.0.edge_references(),
139        }
140    }
141}
142
143/// A reversed edge references iterator.
144pub struct ReversedEdgeReferences<I> {
145    iter: I,
146}
147
148impl<I> Iterator for ReversedEdgeReferences<I>
149where
150    I: Iterator,
151    I::Item: EdgeRef,
152{
153    type Item = ReversedEdgeReference<I::Item>;
154    fn next(&mut self) -> Option<Self::Item> {
155        self.iter.next().map(ReversedEdgeReference)
156    }
157}
158
159macro_rules! access0 {
160    ($e:expr) => {
161        $e.0
162    };
163}
164
165NodeIndexable! {delegate_impl [[G], G, Reversed<G>, access0]}
166NodeCompactIndexable! {delegate_impl [[G], G, Reversed<G>, access0]}
167IntoNodeIdentifiers! {delegate_impl [[G], G, Reversed<G>, access0]}
168IntoNodeReferences! {delegate_impl [[G], G, Reversed<G>, access0]}
169GraphProp! {delegate_impl [[G], G, Reversed<G>, access0]}
170NodeCount! {delegate_impl [[G], G, Reversed<G>, access0]}