1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-11 18:20:28 +09:00
any-sync/acl/testutils/threadbuilder/threadbuildergraph_nix.go
2022-07-13 19:17:50 +03:00

162 lines
3.4 KiB
Go

//go:build (linux || darwin) && !android && !ios && !nographviz && (amd64 || arm64)
// +build linux darwin
// +build !android
// +build !ios
// +build !nographviz
// +build amd64 arm64
package threadbuilder
import (
"fmt"
testpb "github.com/anytypeio/go-anytype-infrastructure-experiments/acl/testutils/testchanges/pb"
"github.com/gogo/protobuf/proto"
"strings"
"unicode"
"github.com/awalterschulze/gographviz"
)
// To quickly look at visualized string you can use https://dreampuf.github.io/GraphvizOnline
type EdgeParameters struct {
style string
color string
label string
}
func (t *ThreadBuilder) Graph() (string, error) {
// TODO: check updates on https://github.com/goccy/go-graphviz/issues/52 or make a fix yourself to use better library here
graph := gographviz.NewGraph()
graph.SetName("G")
graph.SetDir(true)
var nodes = make(map[string]struct{})
var addNodes = func(r *threadChange) error {
// TODO: revisit function after checking
style := "solid"
if r.GetAclData() != nil {
style = "filled"
} else if r.changesDataDecrypted != nil {
style = "dashed"
}
var chSymbs []string
if r.changesDataDecrypted != nil {
res := &testpb.PlainTextChangeData{}
err := proto.Unmarshal(r.changesDataDecrypted, res)
if err != nil {
return err
}
for _, chc := range res.Content {
tp := fmt.Sprintf("%T", chc.Value)
tp = strings.Replace(tp, "ChangeContentValueOf", "", 1)
res := ""
for _, ts := range tp {
if unicode.IsUpper(ts) {
res += string(ts)
}
}
chSymbs = append(chSymbs, res)
}
}
if r.GetAclData() != nil {
for _, chc := range r.GetAclData().AclContent {
tp := fmt.Sprintf("%T", chc.Value)
tp = strings.Replace(tp, "ACLChangeACLContentValueValueOf", "", 1)
res := ""
for _, ts := range tp {
if unicode.IsUpper(ts) {
res += string(ts)
}
}
chSymbs = append(chSymbs, res)
}
}
shortId := r.id
label := fmt.Sprintf("Id: %s\nChanges: %s\n",
shortId,
strings.Join(chSymbs, ","),
)
e := graph.AddNode("G", "\""+r.id+"\"", map[string]string{
"label": "\"" + label + "\"",
"style": "\"" + style + "\"",
})
if e != nil {
return e
}
nodes[r.id] = struct{}{}
return nil
}
var createEdge = func(firstId, secondId string, params EdgeParameters) error {
_, exists := nodes[firstId]
if !exists {
return fmt.Errorf("no such node")
}
_, exists = nodes[secondId]
if !exists {
return fmt.Errorf("no previous node")
}
err := graph.AddEdge("\""+firstId+"\"", "\""+secondId+"\"", true, map[string]string{
"color": params.color,
"style": params.style,
})
if err != nil {
return err
}
return nil
}
var addLinks = func(t *threadChange) error {
for _, prevId := range t.AclHeadIds {
err := createEdge(t.id, prevId, EdgeParameters{
style: "dashed",
color: "red",
})
if err != nil {
return err
}
}
for _, prevId := range t.TreeHeadIds {
err := createEdge(t.id, prevId, EdgeParameters{
style: "dashed",
color: "blue",
})
if err != nil {
return err
}
}
if t.SnapshotBaseId != "" {
err := createEdge(t.id, t.SnapshotBaseId, EdgeParameters{
style: "bold",
color: "blue",
})
if err != nil {
return err
}
}
return nil
}
err := t.traverseFromHeads(addNodes)
if err != nil {
return "", err
}
err = t.traverseFromHeads(addLinks)
if err != nil {
return "", err
}
return graph.String(), nil
}