paiagram/export/
graphviz.rs

1use bevy::{ecs::system::RunSystemOnce, prelude::*};
2use moonshine_core::kind::Instance;
3use petgraph::dot;
4
5use crate::graph::{Graph, Station};
6
7pub struct Graphviz;
8
9impl super::ExportObject for Graphviz {
10    fn export_to_buffer(
11        &mut self,
12        world: &mut World,
13        buffer: &mut Vec<u8>,
14        _input: (),
15    ) -> Result<(), Box<dyn std::error::Error>> {
16        world.run_system_once_with(make_dot_string, buffer);
17        Ok(())
18    }
19    fn extension(&self) -> impl AsRef<str> {
20        ".dot"
21    }
22    fn filename(&self) -> impl AsRef<str> {
23        "diagram"
24    }
25}
26
27fn make_dot_string(InMut(buffer): InMut<Vec<u8>>, graph: Res<Graph>, names: Query<&Name>) {
28    let get_node_attr = |_, (_, entity): (_, &Instance<Station>)| {
29        format!(
30            r#"label = "{}""#,
31            names
32                .get(entity.entity())
33                .map_or("<Unknown>".to_string(), |name| name.to_string())
34        )
35    };
36    let get_edge_attr = |_, _| String::new();
37    let dot_string = dot::Dot::with_attr_getters(
38        graph.inner(),
39        &[dot::Config::EdgeNoLabel, dot::Config::NodeNoLabel],
40        &get_edge_attr,
41        &get_node_attr,
42    );
43    buffer.clear();
44    buffer.extend_from_slice(&format!("{:?}", dot_string).into_bytes());
45}