debug.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package debug
  2. import (
  3. "bytes"
  4. "fmt"
  5. "github.com/gobwas/glob/match"
  6. "math/rand"
  7. )
  8. func Graphviz(pattern string, m match.Matcher) string {
  9. return fmt.Sprintf(`digraph G {graph[label="%s"];%s}`, pattern, graphviz_internal(m, fmt.Sprintf("%x", rand.Int63())))
  10. }
  11. func graphviz_internal(m match.Matcher, id string) string {
  12. buf := &bytes.Buffer{}
  13. switch matcher := m.(type) {
  14. case match.BTree:
  15. fmt.Fprintf(buf, `"%s"[label="%s"];`, id, matcher.Value.String())
  16. for _, m := range []match.Matcher{matcher.Left, matcher.Right} {
  17. switch n := m.(type) {
  18. case nil:
  19. rnd := rand.Int63()
  20. fmt.Fprintf(buf, `"%x"[label="<nil>"];`, rnd)
  21. fmt.Fprintf(buf, `"%s"->"%x";`, id, rnd)
  22. default:
  23. sub := fmt.Sprintf("%x", rand.Int63())
  24. fmt.Fprintf(buf, `"%s"->"%s";`, id, sub)
  25. fmt.Fprintf(buf, graphviz_internal(n, sub))
  26. }
  27. }
  28. case match.AnyOf:
  29. fmt.Fprintf(buf, `"%s"[label="AnyOf"];`, id)
  30. for _, m := range matcher.Matchers {
  31. rnd := rand.Int63()
  32. fmt.Fprintf(buf, graphviz_internal(m, fmt.Sprintf("%x", rnd)))
  33. fmt.Fprintf(buf, `"%s"->"%x";`, id, rnd)
  34. }
  35. case match.EveryOf:
  36. fmt.Fprintf(buf, `"%s"[label="EveryOf"];`, id)
  37. for _, m := range matcher.Matchers {
  38. rnd := rand.Int63()
  39. fmt.Fprintf(buf, graphviz_internal(m, fmt.Sprintf("%x", rnd)))
  40. fmt.Fprintf(buf, `"%s"->"%x";`, id, rnd)
  41. }
  42. default:
  43. fmt.Fprintf(buf, `"%s"[label="%s"];`, id, m.String())
  44. }
  45. return buf.String()
  46. }