digraph_rs/
builder.rs

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}