algae_graph/
directed.rs

1/*
2    Appellation: directed <module>
3    Contrib: FL03 <jo3mccain@icloud.com>
4    Description: ... Summary ...
5*/
6use 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}