1use crate::{store::AdjacencyTable, Edge, Node, Weight};
7use crate::{Contain, Graph, GraphExt, Subgraph};
8use serde::{Deserialize, Serialize};
9
10#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
11pub struct DirectedGraph<N = String, V = i64>
12where
13 N: Node,
14 V: Weight,
15{
16 store: AdjacencyTable<N, V>,
17}
18
19impl<N, V> DirectedGraph<N, V>
20where
21 N: Node,
22 V: Weight,
23{
24 pub fn new() -> Self {
25 Self {
26 store: AdjacencyTable::new(),
27 }
28 }
29 pub fn with_capacity(capacity: usize) -> Self {
30 Self {
31 store: AdjacencyTable::with_capacity(capacity),
32 }
33 }
34}
35
36impl<N, V> AsMut<AdjacencyTable<N, V>> for DirectedGraph<N, V>
37where
38 N: Node,
39 V: Weight,
40{
41 fn as_mut(&mut self) -> &mut AdjacencyTable<N, V> {
42 &mut self.store
43 }
44}
45
46impl<N, V> AsRef<AdjacencyTable<N, V>> for DirectedGraph<N, V>
47where
48 N: Node,
49 V: Weight,
50{
51 fn as_ref(&self) -> &AdjacencyTable<N, V> {
52 &self.store
53 }
54}
55
56impl<N, V> Contain<N> for DirectedGraph<N, V>
57where
58 N: Node,
59 V: Weight,
60{
61 fn contains(&self, elem: &N) -> bool {
62 self.store.contains_key(elem)
63 }
64}
65
66impl<N, V> Contain<Edge<N, V>> for DirectedGraph<N, V>
67where
68 N: Node,
69 V: Weight,
70{
71 fn contains(&self, elem: &Edge<N, V>) -> bool {
72 self.edges().contains(elem)
73 }
74}
75
76impl<N, V> Graph<N, V> for DirectedGraph<N, V>
77where
78 N: Node,
79 V: Weight,
80{
81 fn store_mut(&mut self) -> &mut AdjacencyTable<N, V> {
82 &mut self.store
83 }
84 fn store(&self) -> &AdjacencyTable<N, V> {
85 &self.store
86 }
87}
88
89impl<N, V> GraphExt<N, V> for DirectedGraph<N, V>
90where
91 N: Node,
92 V: Weight,
93{
94}
95
96impl<N, V> Subgraph<N, V> for DirectedGraph<N, V>
97where
98 N: Node,
99 V: Weight,
100{
101}
102
103impl<N, V> From<AdjacencyTable<N, V>> for DirectedGraph<N, V>
104where
105 N: Node,
106 V: Weight,
107{
108 fn from(store: AdjacencyTable<N, V>) -> Self {
109 Self { store }
110 }
111}
112
113impl<N, V> std::ops::Index<N> for DirectedGraph<N, V>
114where
115 N: Node,
116 V: Weight,
117{
118 type Output = Vec<(N, V)>;
119
120 fn index(&self, index: N) -> &Self::Output {
121 self.store.get(&index).unwrap()
122 }
123}
124
125impl<N, V> std::ops::IndexMut<N> for DirectedGraph<N, V>
126where
127 N: Node,
128 V: Weight,
129{
130 fn index_mut(&mut self, index: N) -> &mut Self::Output {
131 self.store.get_mut(&index).unwrap()
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138 use crate::cmp::Edge;
139
140 const TEST_EDGES: [(&str, &str, usize); 3] = [("a", "b", 5), ("c", "a", 7), ("b", "c", 10)];
141
142 #[test]
143 fn test_add_node() {
144 let mut graph = DirectedGraph::<&str, i64>::new();
145 graph.add_node("a");
146 graph.add_node("b");
147 graph.add_node("c");
148 assert_eq!(graph.nodes(), ["a", "b", "c"].iter().cloned().collect());
149 }
150
151 #[test]
152 fn test_add_edge() {
153 let mut graph = DirectedGraph::new();
154
155 for i in TEST_EDGES {
156 graph.add_edge(i.into());
157 }
158 for edge in TEST_EDGES {
159 assert!(graph.contains(&Edge::from(edge)));
160 }
161 }
162
163 #[test]
164 fn test_neighbours() {
165 let mut graph = DirectedGraph::new();
166
167 for i in TEST_EDGES {
168 graph.add_edge(i.into());
169 }
170
171 assert_eq!(graph.neighbors("a").unwrap(), &vec![("b", 5)]);
172 }
173
174 #[test]
175 fn test_contains() {
176 let mut graph = DirectedGraph::<&str, i64>::new();
177 graph.add_node("a");
178 graph.add_node("b");
179 graph.add_node("c");
180 assert!(graph.contains_all(["a", "b", "c"]));
181 assert!(graph.contains_some(["a", "b", "c", "d"]));
182 }
183}