diff --git a/graph/encoding/dot/decode.go b/graph/encoding/dot/decode.go index ccc2868d..a001bbd2 100644 --- a/graph/encoding/dot/decode.go +++ b/graph/encoding/dot/decode.go @@ -54,6 +54,9 @@ func copyGraph(dst encoding.Builder, src *ast.Graph) (err error) { directed: src.Directed, ids: make(map[string]graph.Node), } + if dst, ok := dst.(DOTIDSetter); ok { + dst.SetDOTID(src.ID) + } if a, ok := dst.(AttributeSetters); ok { gen.graphAttr, gen.nodeAttr, gen.edgeAttr = a.DOTAttributeSetters() } diff --git a/graph/encoding/dot/decode_test.go b/graph/encoding/dot/decode_test.go index d05b0507..c345c427 100644 --- a/graph/encoding/dot/decode_test.go +++ b/graph/encoding/dot/decode_test.go @@ -26,6 +26,14 @@ func TestRoundTrip(t *testing.T) { want: undirected, directed: false, }, + { + want: directedID, + directed: true, + }, + { + want: undirectedID, + directed: false, + }, } for i, g := range golden { var dst encoding.Builder @@ -94,6 +102,24 @@ const undirected = `graph { A -- B [label="baz 2"]; }` +const directedID = `digraph G { + // Node definitions. + A; + B; + + // Edge definitions. + A -> B; +}` + +const undirectedID = `graph H { + // Node definitions. + A; + B; + + // Edge definitions. + A -- B; +}` + // Below follows a minimal implementation of a graph capable of validating the // round-trip encoding and decoding of DOT graphs with nodes and edges // containing DOT attributes. @@ -101,9 +127,11 @@ const undirected = `graph { // dotDirectedGraph extends simple.DirectedGraph to add NewNode and NewEdge // methods for creating user-defined nodes and edges. // -// dotDirectedGraph implements the dot.Builder interface. +// dotDirectedGraph implements the encoding.Builder and the dot.Graph +// interfaces. type dotDirectedGraph struct { *simple.DirectedGraph + id string graph, node, edge attributes } @@ -133,12 +161,24 @@ func (g *dotDirectedGraph) DOTAttributeSetters() (graph, node, edge encoding.Att return &g.graph, &g.node, &g.edge } +// SetDOTID sets the DOT ID of the graph. +func (g *dotDirectedGraph) SetDOTID(id string) { + g.id = id +} + +// DOTID returns the DOT ID of the graph. +func (g *dotDirectedGraph) DOTID() string { + return g.id +} + // dotUndirectedGraph extends simple.UndirectedGraph to add NewNode and NewEdge // methods for creating user-defined nodes and edges. // -// dotUndirectedGraph implements the dot.Builder interface. +// dotUndirectedGraph implements the encoding.Builder and the dot.Graph +// interfaces. type dotUndirectedGraph struct { *simple.UndirectedGraph + id string graph, node, edge attributes } @@ -168,6 +208,16 @@ func (g *dotUndirectedGraph) DOTAttributeSetters() (graph, node, edge encoding.A return &g.graph, &g.node, &g.edge } +// SetDOTID sets the DOT ID of the graph. +func (g *dotUndirectedGraph) SetDOTID(id string) { + g.id = id +} + +// DOTID returns the DOT ID of the graph. +func (g *dotUndirectedGraph) DOTID() string { + return g.id +} + // dotNode extends simple.Node with a label field to test round-trip encoding // and decoding of node DOT label attributes. type dotNode struct {