1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use petgraph::{
	data::{Build as PetgraphBuild, DataMap as PetgraphDataMap, DataMapMut as PetgraphDataMapMut},
	visit::{Data as PetgraphData, GraphBase as PetgraphGraphBase},
};

use petgraph::{
	graph::{Graph, IndexType},
	visit::EdgeRef,
	EdgeType,
};

use crate::{
	GraphBase, GraphEdgeAddable, GraphEdgeEndpoints, GraphEdgeFrom, GraphEdgeIndexable,
	GraphEdgeMutIndexable, GraphEdgeRemovable, GraphEdgeTo, GraphEdgesFrom, GraphNodeAddable,
	GraphNodeIndexable, GraphNodeMutIndexable, GraphNodeRemovable,
};

impl<T> GraphBase for T
where
	T: PetgraphGraphBase,
{
	type NodeID = T::NodeId;
	type EdgeID = T::EdgeId;
}

impl<N, T> GraphNodeAddable<N> for T
where
	T: PetgraphBuild + PetgraphData<NodeWeight = N>,
{
	fn add_node(&mut self, data: N) -> Self::NodeID { self.add_node(data) }
}

impl<E, T> GraphEdgeAddable<E> for T
where
	T: PetgraphBuild + PetgraphData<EdgeWeight = E>,
{
	fn add_edge(&mut self, a: Self::NodeID, b: Self::NodeID, data: E) -> Self::EdgeID {
		self.add_edge(a, b, data).unwrap()
	}
}

impl<N, T> GraphNodeIndexable<N> for T
where
	T: PetgraphDataMap + PetgraphData<NodeWeight = N>,
{
	fn node(&self, id: Self::NodeID) -> &N { self.node_weight(id).unwrap() }
}

impl<N, T> GraphNodeMutIndexable<N> for T
where
	T: PetgraphDataMapMut + PetgraphData<NodeWeight = N>,
{
	fn node_mut(&mut self, id: Self::NodeID) -> &mut N { self.node_weight_mut(id).unwrap() }
}

impl<E, T> GraphEdgeIndexable<E> for T
where
	T: PetgraphDataMap + PetgraphData<EdgeWeight = E>,
{
	fn edge(&self, id: Self::EdgeID) -> &E { self.edge_weight(id).unwrap() }
}

impl<E, T> GraphEdgeMutIndexable<E> for T
where
	T: PetgraphDataMapMut + PetgraphData<EdgeWeight = E>,
{
	fn edge_mut(&mut self, id: Self::EdgeID) -> &mut E { self.edge_weight_mut(id).unwrap() }
}

// Petgraph does not have some traits which align with some of the traits in this crate therefore we implement per-struct

impl<N, E, Ty, Ix> GraphNodeRemovable<N> for Graph<N, E, Ty, Ix>
where
	Ty: EdgeType,
	Ix: IndexType,
{
	fn remove_node(&mut self, id: Self::NodeID) -> N { self.remove_node(id).unwrap() }
}

impl<N, E, Ty, Ix> GraphEdgeRemovable<E> for Graph<N, E, Ty, Ix>
where
	Ty: EdgeType,
	Ix: IndexType,
{
	fn remove_edge(&mut self, id: Self::EdgeID) -> E { self.remove_edge(id).unwrap() }
}

impl<N, E, Ty, Ix> GraphEdgeTo for Graph<N, E, Ty, Ix>
where
	Ty: EdgeType,
	Ix: IndexType,
{
	fn edge_to(&self, id: Self::EdgeID) -> Self::NodeID { self.edge_endpoints(id).unwrap().1 }
}

impl<N, E, Ty, Ix> GraphEdgeFrom for Graph<N, E, Ty, Ix>
where
	Ty: EdgeType,
	Ix: IndexType,
{
	fn edge_from(&self, id: Self::EdgeID) -> Self::NodeID { self.edge_endpoints(id).unwrap().0 }
}

impl<N, E, Ty, Ix> GraphEdgeEndpoints for Graph<N, E, Ty, Ix>
where
	Ty: EdgeType,
	Ix: IndexType,
{
	fn edge_endpoints(&self, id: Self::EdgeID) -> (Self::NodeID, Self::NodeID) {
		self.edge_endpoints(id).unwrap()
	}
}

impl<N, E, Ty, Ix> GraphEdgesFrom for Graph<N, E, Ty, Ix>
where
	Ty: EdgeType,
	Ix: IndexType,
{
	type EdgesFromOutput = Vec<Self::EdgeID>;

	fn edges_from(&self, id: Self::NodeID) -> Self::EdgesFromOutput {
		self.edges(id).map(|edge_ref| edge_ref.id()).collect()
	}
}