petgraph/visit/
reversed.rs

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