90 lines
1.8 KiB
Go
90 lines
1.8 KiB
Go
|
package digraph
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// BasicNode is a digraph Node that has a name and out edges
|
||
|
type BasicNode struct {
|
||
|
Name string
|
||
|
NodeEdges []Edge
|
||
|
}
|
||
|
|
||
|
func (b *BasicNode) Edges() []Edge {
|
||
|
return b.NodeEdges
|
||
|
}
|
||
|
|
||
|
func (b *BasicNode) AddEdge(edge Edge) {
|
||
|
b.NodeEdges = append(b.NodeEdges, edge)
|
||
|
}
|
||
|
|
||
|
func (b *BasicNode) String() string {
|
||
|
if b.Name == "" {
|
||
|
return "Node"
|
||
|
}
|
||
|
return fmt.Sprintf("%v", b.Name)
|
||
|
}
|
||
|
|
||
|
// BasicEdge is a digraph Edge that has a name, head and tail
|
||
|
type BasicEdge struct {
|
||
|
Name string
|
||
|
EdgeHead *BasicNode
|
||
|
EdgeTail *BasicNode
|
||
|
}
|
||
|
|
||
|
func (b *BasicEdge) Head() Node {
|
||
|
return b.EdgeHead
|
||
|
}
|
||
|
|
||
|
// Tail returns the end point of the Edge
|
||
|
func (b *BasicEdge) Tail() Node {
|
||
|
return b.EdgeTail
|
||
|
}
|
||
|
|
||
|
func (b *BasicEdge) String() string {
|
||
|
if b.Name == "" {
|
||
|
return "Edge"
|
||
|
}
|
||
|
return fmt.Sprintf("%v", b.Name)
|
||
|
}
|
||
|
|
||
|
// ParseBasic is used to parse a string in the format of:
|
||
|
// a -> b ; edge name
|
||
|
// b -> c
|
||
|
// Into a series of basic node and basic edges
|
||
|
func ParseBasic(s string) map[string]*BasicNode {
|
||
|
lines := strings.Split(s, "\n")
|
||
|
nodes := make(map[string]*BasicNode)
|
||
|
for _, line := range lines {
|
||
|
var edgeName string
|
||
|
if idx := strings.Index(line, ";"); idx >= 0 {
|
||
|
edgeName = strings.Trim(line[idx+1:], " \t\r\n")
|
||
|
line = line[:idx]
|
||
|
}
|
||
|
parts := strings.SplitN(line, "->", 2)
|
||
|
if len(parts) != 2 {
|
||
|
continue
|
||
|
}
|
||
|
head_name := strings.Trim(parts[0], " \t\r\n")
|
||
|
tail_name := strings.Trim(parts[1], " \t\r\n")
|
||
|
head := nodes[head_name]
|
||
|
if head == nil {
|
||
|
head = &BasicNode{Name: head_name}
|
||
|
nodes[head_name] = head
|
||
|
}
|
||
|
tail := nodes[tail_name]
|
||
|
if tail == nil {
|
||
|
tail = &BasicNode{Name: tail_name}
|
||
|
nodes[tail_name] = tail
|
||
|
}
|
||
|
edge := &BasicEdge{
|
||
|
Name: edgeName,
|
||
|
EdgeHead: head,
|
||
|
EdgeTail: tail,
|
||
|
}
|
||
|
head.AddEdge(edge)
|
||
|
}
|
||
|
return nodes
|
||
|
}
|