1#[macro_export]
2macro_rules! extend_nodes {
3 ($graph:ident => [$(($id:expr, $p:expr)),+ $(,)?]) => {{
4 $(
5 $graph.add_node($id,$p);
6 )+
7 $graph
8 }};
9
10 ($graph:ident => [$($id:expr),+ $(,)?]) => {{
11 $(
12 $graph.add_bare_node($id);
13 )+
14 $graph
15 }};
16}
17
18#[macro_export]
19macro_rules! extend_edges {
20 ($graph:expr => {}) => {{
21 $graph
22 }};
23
24 ($graph:expr => {[$(($from:expr,$p:expr)),+ $(,)?] => $to:expr; $($rest:tt)*}) => {{
25 $(
26 $graph.add_edge($from,$to,$p);
27 )+
28 extend_edges!($graph => {$($rest)*})
29 }};
30
31 ($graph:expr => {[$(($from:expr,$p:expr)),+ $(,)?] => $to:expr $(;)?}) => {{
32 $(
33 $graph.add_edge($from,$to,$p);
34 )+
35 $graph
36 }};
37 ($graph:expr => {[$($from:expr),+ $(,)?] => ($to:expr,$p:expr) $(;)?}) => {{
38
39 $(
40 $graph.add_edge($from,$to,$p);
41 )+
42
43 $graph
44 }};
45 ($graph:expr => {[$($from:expr),+ $(,)?] => ($to:expr,$p:expr) ; $($rest:tt)*}) => {{
46
47 $(
48 $graph.add_edge($from,$to,$p);
49 )+
50
51 extend_edges!($graph => {$($rest)*})
52 }};
53 ($graph:expr => {[$($from:expr),+ $(,)?] => $to:expr $(;)?}) => {{
54 $(
55 $graph.add_bare_edge($from,$to);
56 )+
57 $graph
58 }};
59 ($graph:expr => {[$($from:expr),+ $(,)?] => $to:expr ; $($rest:tt)*}) => {{
60 $(
61 $graph.add_bare_edge($from,$to);
62 )+
63 extend_edges!($graph => {$($rest)*})
64 }};
65
66 ($graph:expr => {$from:expr => [$(($to:expr,$p:expr)),+ $(,)?] $(;)? }) => {{
67 $(
68 $graph.add_edge($from,$to,$p);
69 )+
70 $graph
71 }};
72 ($graph:expr => {$from:expr => [$(($to:expr,$p:expr)),+ $(,)?] ; $($rest:tt)*}) => {{
73 $(
74 $graph.add_edge($from,$to,$p);
75 )+
76 extend_edges!($graph => {$($rest)*})
77 }};
78 ($graph:expr => {$from:expr => [$($to:expr),+ $(,)?] $(;)?}) => {{
79 $(
80 $graph.add_bare_edge($from,$to);
81 )+
82 $graph
83 }};
84 ($graph:expr => {$from:expr => [$($to:expr),+ $(,)?] ; $($rest:tt)*}) => {{
85 $(
86 $graph.add_bare_edge($from,$to);
87 )+
88 extend_edges!($graph => {$($rest)*})
89 }};
90
91 ($graph:expr => {$from:expr => ($to:expr,$p:expr) $(;)?}) => {{
92 $graph.add_edge($from,$to,$p);
93 $graph
94 }};
95 ($graph:expr => {$from:expr => ($to:expr,$p:expr); $($rest:tt)*}) => {{
96 $graph.add_edge($from,$to,$p);
97 extend_edges!($graph => {$($rest)*})
98 }};
99 ($graph:expr => {$from:expr => $to:expr $(;)?}) => {{
100 $graph.add_bare_edge($from,$to);
101 $graph
102 }};
103 ($graph:expr => {$from:expr => $to:expr; $($rest:tt)*}) => {{
104 $graph.add_bare_edge($from,$to);
105 extend_edges!($graph => {$($rest)*})
106 }};
107}
108
109#[macro_export]
110macro_rules! digraph {
111 () => {
112 DiGraph::empty()
113 };
114
115 (_ , $n:ty,_ ) => {
116 DiGraph::<usize,$n,EmptyPayload>::new()
117 };
118 ( $id:ty,_,_) => {
119 DiGraph::<$id,EmptyPayload,EmptyPayload>::new()
120 };
121 ( _,_,$e:ty) => {
122 DiGraph::<usize,EmptyPayload,$e>::new()
123 };
124 ( _, $n:ty, $e:ty) => {
125 DiGraph::<usize,$n,$e>::new()
126 };
127
128 ( $id:ty,_, $e:ty) => {
129 DiGraph::<$id,EmptyPayload,$e>::new()
130 };
131
132 ( $id:ty,$n:ty, $e:ty) => {
133 DiGraph::<$id,$n,$e>::new()
134 };
135
136 (($($tps:tt)+) => $nodes:tt ) => {{
137 let mut g = digraph!($($tps)+);
138 extend_nodes!(g => $nodes)
139 }};
140
141
142 (($($tps:tt)+)=> $nodes:tt => $edges:tt) => {{
143 let mut g = digraph!($($tps)+);
144 let mut g = extend_nodes!(g => $nodes);
145 extend_edges!(g => $edges)
146 }};
147
148
149 ( => $nodes:tt ) => {{
150 let mut g = digraph!();
151 extend_nodes!(g => $nodes)
152 }};
153
154 (=> $nodes:tt => $edges:tt) => {{
155 let mut g = digraph!();
156 let mut g = extend_nodes!(g => $nodes);
157 extend_edges!(g => $edges)
158 }};
159
160}
161
162#[cfg(test)]
163mod tests {
164 use crate::digraph;
165 use crate::{DiGraph, EmptyPayload};
166 use std::collections::HashMap;
167
168 #[derive(Default)]
169 struct S(i32);
170
171 impl S {
172 pub fn new(i: i32) -> Self {
173 Self { 0: i }
174 }
175 }
176
177 #[test]
178 fn simple_macro_v_d_test() {
179 let d = digraph!();
180 let d = digraph!(_, S, usize);
181 let d = digraph!(_, S, S);
182 let d = digraph!(_, S, _);
183 let d = digraph!(_, _, S);
184 let d = digraph!(_, bool, S);
185 let d = digraph!(=> [1,2,3]);
186 assert_eq!(
187 d.nodes,
188 HashMap::from([(1, EmptyPayload), (2, EmptyPayload), (3, EmptyPayload)])
189 );
190
191 let d = digraph!((_,i32,_) => [(1,1),(2,2),(3,0)]);
192 assert_eq!(d.nodes, HashMap::from([(1, 1), (2, 2), (3, 0)]));
193
194 let d = digraph!(
195 (_,_,i32) => [1,2,3,4] => {
196 1 => 2;
197 2 => (3,1);
198 [4,3] => 1;
199 }
200 );
201 assert_eq!(
202 d.nodes,
203 HashMap::from([
204 (1, EmptyPayload),
205 (2, EmptyPayload),
206 (3, EmptyPayload),
207 (4, EmptyPayload)
208 ])
209 );
210 assert_eq!(
211 d.edges,
212 HashMap::from([
213 (1, HashMap::from([(2, 0)])),
214 (2, HashMap::from([(3, 1)])),
215 (3, HashMap::from([(1, 0)])),
216 (4, HashMap::from([(1, 0)])),
217 ])
218 );
219 }
220 #[test]
221 fn simple_diff_key_macro_test() {
222 let d = digraph!(String, _, _);
223 let d = digraph!((&str,_,_) => ["1","2","3"]);
224 assert_eq!(
225 d.nodes,
226 HashMap::from([
227 ("1", EmptyPayload),
228 ("2", EmptyPayload),
229 ("3", EmptyPayload)
230 ])
231 );
232
233 let mut g = digraph!((&str,_,i32) => ["a","b","c"] => {
234 "a" => "b";
235 ["a","b"] => "c";
236 });
237
238 let f = g.edges;
239
240 assert_eq!(f.get("a"), Some(&HashMap::from([("b", 0), ("c", 0)])));
241 assert_eq!(f.get("b"), Some(&HashMap::from([("c", 0)])));
242 }
243
244 #[test]
245 fn builder_nodes_test() {
246 let mut g = digraph!(_, usize, _);
247 let g = extend_nodes!(g => [(1,1),(2,1)]);
248 assert_eq!(g.nodes, HashMap::from([(1, 1), (2, 1)]));
249
250 let mut g = digraph!(_, usize, _);
251 let def_p = 100;
252 let g = extend_nodes!(g => [(1,def_p),(2,def_p)]);
253 assert_eq!(g.nodes, HashMap::from([(1, 100), (2, 100)]));
254 }
255
256 #[test]
257 fn builder_edges_arr_to_test() {
258 let mut g = digraph!(_, _, i32);
259 let mut g = extend_nodes!(g => [1,2,3,4,5,6,7]);
260 let mut g = extend_edges!(g => {
261 [(2,1),(3,1)] => 4
262 });
263 assert_eq!(
264 g.edges,
265 HashMap::from([(2, HashMap::from([(4, 1)])), (3, HashMap::from([(4, 1)])),])
266 );
267
268 let mut g = digraph!(_, _, i32);
269 let mut g = extend_nodes!(g => [1,2,3,4,5,6,7]);
270 let g = extend_edges!(g => {
271 [(4,1),(1,1)] => 5;
272 [(5,1),(6,1)] => 7;
273 });
274 assert_eq!(
275 g.edges,
276 HashMap::from([
277 (4, HashMap::from([(5, 1)])),
278 (1, HashMap::from([(5, 1)])),
279 (5, HashMap::from([(7, 1)])),
280 (6, HashMap::from([(7, 1)])),
281 ])
282 );
283
284 let mut g = digraph!(_, _, i32);
285 let mut g = extend_nodes!(g => [1,2,3,4,5,6,7]);
286 let mut g = extend_edges!(g => {
287 [1,2] => (3,10)
288 });
289 assert_eq!(
290 g.edges,
291 HashMap::from([(2, HashMap::from([(3, 10)])), (1, HashMap::from([(3, 10)])),])
292 );
293
294 let mut g = extend_edges!(g => {
295 [1,2] => (3,10);
296 [3,4] => (5,1);
297 [(5,1),(6,10)] => 7
298 });
299 assert_eq!(
300 g.edges,
301 HashMap::from([
302 (2, HashMap::from([(3, 10)])),
303 (1, HashMap::from([(3, 10)])),
304 (3, HashMap::from([(5, 1)])),
305 (4, HashMap::from([(5, 1)])),
306 (5, HashMap::from([(7, 1)])),
307 (6, HashMap::from([(7, 10)])),
308 ])
309 );
310
311 let mut g = digraph!();
312 let mut g = extend_nodes!(g => [1,2,3,4,5,6,7]);
313 let mut g = extend_edges!(g => {
314 [1,2] => 3
315 });
316 assert_eq!(
317 g.edges,
318 HashMap::from([
319 (2, HashMap::from([(3, EmptyPayload)])),
320 (1, HashMap::from([(3, EmptyPayload)])),
321 ])
322 );
323 let mut g = extend_edges!(g => {
324 [1,2] => 3;
325 [3,4] => 5;
326 });
327 assert_eq!(
328 g.edges,
329 HashMap::from([
330 (2, HashMap::from([(3, EmptyPayload)])),
331 (1, HashMap::from([(3, EmptyPayload)])),
332 (3, HashMap::from([(5, EmptyPayload)])),
333 (4, HashMap::from([(5, EmptyPayload)])),
334 ])
335 );
336
337 let mut g = extend_edges!(g => {
338 5 => [6,7];
339 6 => [7,1];
340 });
341 assert_eq!(
342 g.edges,
343 HashMap::from([
344 (2, HashMap::from([(3, EmptyPayload)])),
345 (1, HashMap::from([(3, EmptyPayload)])),
346 (3, HashMap::from([(5, EmptyPayload)])),
347 (4, HashMap::from([(5, EmptyPayload)])),
348 (5, HashMap::from([(7, EmptyPayload), (6, EmptyPayload)])),
349 (6, HashMap::from([(7, EmptyPayload), (1, EmptyPayload)])),
350 ])
351 );
352
353 let mut g = digraph!(_, _, i32);
354 let mut g = extend_nodes!(g => [1,2,3,4,5,6,7]);
355 let g = extend_edges!(g => {
356 [(1,1),(2,1)] => 3;
357 [(3,1)] => 4;
358 4 => [(5,1),(6,1)];
359 7 => [1,2]
360
361 });
362 assert_eq!(
363 g.edges,
364 HashMap::from([
365 (1, HashMap::from([(3, 1)])),
366 (2, HashMap::from([(3, 1)])),
367 (3, HashMap::from([(4, 1)])),
368 (4, HashMap::from([(5, 1), (6, 1)])),
369 (7, HashMap::from([(1, 0), (2, 0)])),
370 ])
371 );
372 }
373
374 #[test]
375 fn builder_edges_simple_to_test() {
376 let mut g = digraph!(_, _, i32);
377 let mut g = extend_nodes!(g => [1,2,3,4,5,6,7]);
378 let mut g = extend_edges!(g => {
379 1 => [1,2];
380 2 => 3;
381 3 => 4;
382 4 => (5,7);
383 5 => (6,1);
384 7 => 1
385 });
386
387 let f = g.edges;
388
389 assert_eq!(f.get(&1), Some(&HashMap::from([(1, 0), (2, 0)])));
390 assert_eq!(f.get(&2), Some(&HashMap::from([(3, 0)])));
391 assert_eq!(f.get(&3), Some(&HashMap::from([(4, 0)])));
392 assert_eq!(f.get(&4), Some(&HashMap::from([(5, 7)])));
393 assert_eq!(f.get(&7), Some(&HashMap::from([(1, 0)])));
394 }
395}