digraph_rs/visualizer/
dot.rs

1use crate::{DiGraph, EmptyPayload};
2use graphviz_rust::attributes::{EdgeAttributes, NodeAttributes};
3use graphviz_rust::cmd::{CommandArg, Format};
4use graphviz_rust::dot_generator::*;
5use graphviz_rust::dot_structures::*;
6use graphviz_rust::printer::{DotPrinter, PrinterContext};
7use graphviz_rust::{exec, exec_dot};
8use std::hash::Hash;
9
10pub trait DotProcessor<'a, NId, NL, EL> {
11    fn node(&self, id: &'a NId, nl: &'a NL) -> Stmt;
12    fn edge(&self, from: &'a NId, to: &'a NId, el: &'a EL) -> Stmt;
13}
14
15pub struct ToStringProcessor;
16
17impl ToStringProcessor {
18    pub fn node_with_attrs<'a, NId, NL>(
19        &self,
20        id: &'a NId,
21        nl: &'a NL,
22        attrs: Vec<Attribute>,
23    ) -> Stmt
24    where
25        NId: ToString,
26        NL: ToString,
27    {
28        let id = id.to_string();
29        let label = format!("\"{} {}\"", id, nl.to_string());
30        let mut attrs = attrs;
31        attrs.push(NodeAttributes::label(label));
32        stmt!(node!(id.as_str(), attrs))
33    }
34    pub fn edge_with_attrs<'a, NId, EL>(
35        &self,
36        from: &'a NId,
37        to: &'a NId,
38        el: &'a EL,
39        attrs: Vec<Attribute>,
40    ) -> Stmt
41    where
42        NId: ToString,
43        EL: ToString,
44    {
45        let from = format!("{}", from.to_string());
46        let to = format!("{}", to.to_string());
47        let label = format!("{}", el.to_string());
48        let mut attrs = attrs;
49        attrs.push(EdgeAttributes::label(label));
50
51        stmt!(edge!(node_id!(from.as_str()) => node_id!(to.as_str()), attrs))
52    }
53}
54
55impl<'a, NId, NL, EL> DotProcessor<'a, NId, NL, EL> for ToStringProcessor
56where
57    NId: ToString,
58    NL: ToString,
59    EL: ToString,
60{
61    fn node(&self, id: &'a NId, nl: &'a NL) -> Stmt {
62        self.node_with_attrs(id, nl, vec![])
63    }
64
65    fn edge(&self, from: &'a NId, to: &'a NId, el: &'a EL) -> Stmt {
66        self.edge_with_attrs(from, to, el, vec![])
67    }
68}
69
70#[cfg(test)]
71mod tests {
72
73    use crate::visualizer::{vis, vis_to_file};
74    use crate::DiGraph;
75    use crate::EmptyPayload;
76    use crate::*;
77    use graphviz_rust::dot_structures::Graph;
78
79    #[test]
80    fn simple_viz_to_file_test() {
81        let dot = digraph!(
82            => [1,2,3,4,5,6,7,8,9,10] => {
83             1 => [2,3,4];
84             [2,3,4] => 5;
85             [2,3,4] => 6;
86             5 => 6;
87             6 => [7,8];
88             [7,8] => 9;
89             9 => 10
90            }
91        )
92        .visualize()
93        .str_to_dot_file("dots/output.svg");
94        println!("{:?}", dot)
95    }
96    #[test]
97    fn simple_viz_to_file_payload_edge_test() {
98        let dot = digraph!(
99           (_,_,i32) => [1,2,3,4,5,6,7,8,9,10] => {
100             1 => [2,3,4];
101             [2,3,4] => (5,100);
102             [2,3,4] => (6,10);
103             5 => (6,1);
104             6 => [(7,14),(8,14)];
105             [7,8] => 9;
106             9 => 10
107            }
108        )
109        .visualize()
110        .str_to_dot_file("dots/output.svg");
111        println!("{:?}", dot)
112    }
113    #[test]
114    fn simple_viz_to_file_str_edge_test() {
115        let dot = digraph!(
116           (&str,_,_) => ["company","employer","employee"] => {
117                "employer" => "company";
118                "company" => "employee"
119            }
120        )
121        .visualize()
122        .str_to_dot_file("dots/output.svg");
123
124        println!("{:?}", dot)
125    }
126}