1use super::{GraphConversion, IOError};
2use crate::{
3 utils::{fill_bitvector, get_size},
4 WriteGraph,
5};
6
7#[derive(Debug)]
9pub struct DiGraph {
10 pub bit_vec: Vec<usize>,
11 pub n: usize,
12}
13impl DiGraph {
14 pub fn from_d6(repr: &str) -> Result<Self, IOError> {
30 let bytes = repr.as_bytes();
31 Self::valid_digraph(bytes)?;
32 let n = get_size(bytes, 1)?;
33 let bit_vec = Self::build_bitvector(bytes, n);
34 Ok(Self { bit_vec, n })
35 }
36
37 pub fn from_adj(adj: &[usize]) -> Result<Self, IOError> {
53 let n2 = adj.len();
54 let n = (n2 as f64).sqrt() as usize;
55 if n * n != n2 {
56 return Err(IOError::InvalidAdjacencyMatrix);
57 }
58 let bit_vec = adj.to_vec();
59 Ok(Self { bit_vec, n })
60 }
61
62 fn valid_digraph(repr: &[u8]) -> Result<bool, IOError> {
64 if repr[0] == b'&' {
65 Ok(true)
66 } else {
67 Err(IOError::InvalidDigraphHeader)
68 }
69 }
70
71 fn build_bitvector(bytes: &[u8], n: usize) -> Vec<usize> {
74 let bv_len = n * n;
75 let bit_vec = fill_bitvector(bytes, bv_len, 2);
76 bit_vec
77 }
78}
79
80impl GraphConversion for DiGraph {
81 fn bit_vec(&self) -> &[usize] {
82 &self.bit_vec
83 }
84
85 fn size(&self) -> usize {
86 self.n
87 }
88
89 fn is_directed(&self) -> bool {
90 true
91 }
92}
93
94impl WriteGraph for DiGraph {}
95
96#[cfg(test)]
97mod testing {
98 use crate::WriteGraph;
99
100 use super::GraphConversion;
101
102 #[test]
103 fn test_header() {
104 let repr = b"&AG";
105 assert!(super::DiGraph::valid_digraph(repr).is_ok());
106 }
107
108 #[test]
109 fn test_invalid_header() {
110 let repr = b"AG";
111 assert!(super::DiGraph::valid_digraph(repr).is_err());
112 }
113
114 #[test]
115 fn test_from_adj() {
116 let adj = &[0, 0, 1, 0];
117 let graph = super::DiGraph::from_adj(adj).unwrap();
118 assert_eq!(graph.size(), 2);
119 assert_eq!(graph.bit_vec(), vec![0, 0, 1, 0]);
120 assert_eq!(graph.write_graph(), "&AG");
121 }
122
123 #[test]
124 fn test_from_nonsquare_adj() {
125 let adj = &[0, 0, 1, 0, 1];
126 let graph = super::DiGraph::from_adj(adj);
127 assert!(graph.is_err());
128 }
129
130 #[test]
131 fn test_bitvector_n2() {
135 let repr = "&AG";
136 let graph = super::DiGraph::from_d6(repr).unwrap();
137 assert_eq!(graph.size(), 2);
138 assert_eq!(graph.bit_vec(), vec![0, 0, 1, 0]);
139 }
140
141 #[test]
142 fn test_bitvector_n3() {
147 let repr = r"&B\o";
148 let graph = super::DiGraph::from_d6(repr).unwrap();
149 assert_eq!(graph.size(), 3);
150 assert_eq!(graph.bit_vec(), vec![0, 1, 1, 1, 0, 1, 1, 1, 0]);
151 }
152
153 #[test]
154 fn test_bitvector_n4() {
160 let repr = r"&C]|w";
161 let graph = super::DiGraph::from_d6(repr).unwrap();
162 assert_eq!(graph.size(), 4);
163 assert_eq!(
164 graph.bit_vec(),
165 vec![0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0]
166 );
167 }
168
169 #[test]
170 fn test_init_invalid_n2() {
171 let repr = "AG";
172 let graph = super::DiGraph::from_d6(repr);
173 assert!(graph.is_err());
174 }
175
176 #[test]
177 fn test_to_adjacency() {
178 let repr = r"&C]|w";
179 let graph = super::DiGraph::from_d6(repr).unwrap();
180 let adj = graph.to_adjmat();
181 assert_eq!(adj, "0 1 1 1\n1 0 1 1\n1 1 0 1\n1 1 1 0\n");
182 }
183
184 #[test]
185 fn test_to_dot() {
186 let repr = r"&AG";
187 let graph = super::DiGraph::from_d6(repr).unwrap();
188 let dot = graph.to_dot(None);
189 assert_eq!(dot, "digraph {\n1 -> 0;\n}");
190 }
191
192 #[test]
193 fn test_to_dot_with_id() {
194 let repr = r"&AG";
195 let graph = super::DiGraph::from_d6(repr).unwrap();
196 let dot = graph.to_dot(Some(1));
197 assert_eq!(dot, "digraph graph_1 {\n1 -> 0;\n}");
198 }
199
200 #[test]
201 fn test_to_net() {
202 let repr = r"&AG";
203 let graph = super::DiGraph::from_d6(repr).unwrap();
204 let net = graph.to_net();
205 assert_eq!(net, "*Vertices 2\n1 \"0\"\n2 \"1\"\n*Arcs\n2 1\n");
206 }
207
208 #[test]
209 fn test_to_flat() {
210 let repr = r"&AG";
211 let graph = super::DiGraph::from_d6(repr).unwrap();
212 let flat = graph.to_flat();
213 assert_eq!(flat, "0010");
214 }
215
216 #[test]
217 fn test_write_n2() {
218 let repr = r"&AG";
219 let graph = super::DiGraph::from_d6(repr).unwrap();
220 let graph6 = graph.write_graph();
221 assert_eq!(graph6, repr);
222 }
223
224 #[test]
225 fn test_write_n3() {
226 let repr = r"&B\o";
227 let graph = super::DiGraph::from_d6(repr).unwrap();
228 let graph6 = graph.write_graph();
229 assert_eq!(graph6, repr);
230 }
231
232 #[test]
233 fn test_write_n4() {
234 let repr = r"&C]|w";
235 let graph = super::DiGraph::from_d6(repr).unwrap();
236 let graph6 = graph.write_graph();
237 assert_eq!(graph6, repr);
238 }
239}