diff --git a/graph/encoding/dot/decode.go b/graph/encoding/dot/decode.go index 319e0ab5..e7a4d405 100644 --- a/graph/encoding/dot/decode.go +++ b/graph/encoding/dot/decode.go @@ -39,6 +39,12 @@ type UnmarshalerAttr interface { UnmarshalDOTAttr(attr Attribute) error } +// UnmarshalerID is implemented by types that can unmarshal a DOT ID. +type UnmarshalerID interface { + // UnmarshalDOTID decodes a single DOT ID. + UnmarshalDOTID(id string) +} + // Unmarshal parses the Graphviz DOT-encoded data and stores the result in dst. func Unmarshal(data []byte, dst Builder) error { file, err := dot.ParseBytes(data) @@ -100,6 +106,9 @@ func (gen *generator) node(dst Builder, id string) graph.Node { return n } n := dst.NewNode() + if n, ok := n.(UnmarshalerID); ok { + n.UnmarshalDOTID(id) + } gen.ids[id] = n // Check if within the context of a subgraph, that is to be used as a vertex // of an edge. diff --git a/graph/encoding/dot/decode_test.go b/graph/encoding/dot/decode_test.go index d99fdc44..2dea9b24 100644 --- a/graph/encoding/dot/decode_test.go +++ b/graph/encoding/dot/decode_test.go @@ -65,11 +65,11 @@ const directed = `digraph { ]; // Node definitions. - 0 [label="foo 2"]; - 1 [label="bar 2"]; + A [label="foo 2"]; + B [label="bar 2"]; // Edge definitions. - 0 -> 1 [label="baz 2"]; + A -> B [label="baz 2"]; }` const undirected = `graph { @@ -86,11 +86,11 @@ const undirected = `graph { ]; // Node definitions. - 0 [label="foo 2"]; - 1 [label="bar 2"]; + A [label="foo 2"]; + B [label="bar 2"]; // Edge definitions. - 0 -- 1 [label="baz 2"]; + A -- B [label="baz 2"]; }` // Below follows a minimal implementation of a graph capable of validating the @@ -187,10 +187,21 @@ func (g *dotUndirectedGraph) DOTUnmarshalerAttrs() (graph, node, edge Unmarshale // and decoding of node DOT label attributes. type dotNode struct { simple.Node + dotID string // Node label. Label string } +// DOTID returns the node's DOT ID. +func (n *dotNode) DOTID() string { + return n.dotID +} + +// UnmarshalDOTID decodes a DOT ID. +func (n *dotNode) UnmarshalDOTID(id string) { + n.dotID = id +} + // UnmarshalDOTAttr decodes a single DOT attribute. func (n *dotNode) UnmarshalDOTAttr(attr Attribute) error { if attr.Key != "label" {