1use crate::{Graph, GraphErr, VertexId};
2
3#[cfg(feature = "no_std")]
4use core::io::Write;
5
6#[cfg(not(feature = "no_std"))]
7use std::io::Write;
8
9#[cfg(feature = "no_std")]
10use core::borrow::Cow;
11
12#[cfg(not(feature = "no_std"))]
13use std::borrow::Cow;
14
15#[cfg(feature = "no_std")]
16use core::fmt::Debug;
17
18#[cfg(not(feature = "no_std"))]
19use std::fmt::Debug;
20
21type Nd = VertexId;
22type Ed<'a> = (&'a VertexId, &'a VertexId);
23
24
25pub(crate) struct DotGraph<'a, T> {
26 name: dot::Id<'a>,
27 graph: &'a Graph<T>,
28}
29
30
31impl<'a, T> DotGraph<'a, T> {
32 pub fn new(graph: &'a Graph<T>, name: &'a str) -> Result<DotGraph<'a, T>, GraphErr> {
33 let name = dot::Id::new(name)
34 .map_err(|_| GraphErr::InvalidGraphName)?;
35 Ok(DotGraph { name, graph })
36 }
37}
38
39
40impl<'a, T> dot::Labeller<'a, Nd, Ed<'a>> for DotGraph<'a, T> {
41 fn graph_id(&'a self) -> dot::Id<'a> {
42 dot::Id::new(self.name.as_slice()).unwrap()
43 }
44
45 fn node_id(&'a self, n: &Nd) -> dot::Id<'a> {
46 let hex = format!("N{}", hex::encode(n.bytes()));
47 dot::Id::new(hex).unwrap()
48 }
49
50 fn node_label<'b>(&'b self, n: &Nd) -> dot::LabelText<'b> {
51 let label = self.graph.vertex_label(n).unwrap();
52 dot::LabelText::label(Cow::Borrowed(label))
53 }
54
55 fn edge_label<'b>(&'b self, e: &Ed) -> dot::LabelText<'b> {
56 let label = self.graph.edge_label(e.0, e.1).unwrap();
57 dot::LabelText::LabelStr(Cow::Borrowed(label))
58 }
59}
60
61
62impl<'a, T> dot::GraphWalk<'a, Nd, Ed<'a>> for DotGraph<'a, T> {
63 fn nodes(&self) -> dot::Nodes<'a, Nd> {
64 let nodes = self.graph.vertices().cloned().collect();
65 Cow::Owned(nodes)
66 }
67
68 fn edges(&'a self) -> dot::Edges<'a, Ed<'a>> {
69 self.graph.edges()
70 .map(|e| (e.1, e.0))
71 .collect()
72 }
73
74 fn source(&self, e: &Ed) -> Nd {
75 *e.0
76 }
77
78 fn target(&self, e: &Ed) -> Nd {
79 *e.1
80 }
81}
82