56 lines
1.0 KiB
Go
56 lines
1.0 KiB
Go
package query
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
// TODO(nathanielc): Add better options for formatting plans as Graphviz dot format.
|
|
type FormatOption func(*formatter)
|
|
|
|
func Formatted(q *Spec, opts ...FormatOption) fmt.Formatter {
|
|
f := formatter{
|
|
q: q,
|
|
}
|
|
for _, o := range opts {
|
|
o(&f)
|
|
}
|
|
return f
|
|
}
|
|
|
|
func FmtJSON(f *formatter) { f.json = true }
|
|
|
|
type formatter struct {
|
|
q *Spec
|
|
json bool
|
|
}
|
|
|
|
func (f formatter) Format(fs fmt.State, c rune) {
|
|
if c == 'v' && fs.Flag('#') {
|
|
fmt.Fprintf(fs, "%#v", f.q)
|
|
return
|
|
}
|
|
if f.json {
|
|
f.formatJSON(fs)
|
|
} else {
|
|
f.formatDAG(fs)
|
|
}
|
|
}
|
|
func (f formatter) formatJSON(fs fmt.State) {
|
|
e := json.NewEncoder(fs)
|
|
e.SetIndent("", " ")
|
|
e.Encode(f.q)
|
|
}
|
|
|
|
func (f formatter) formatDAG(fs fmt.State) {
|
|
fmt.Fprint(fs, "digraph QuerySpec {\n")
|
|
_ = f.q.Walk(func(o *Operation) error {
|
|
fmt.Fprintf(fs, "%s[kind=%q];\n", o.ID, o.Spec.Kind())
|
|
for _, child := range f.q.Children(o.ID) {
|
|
fmt.Fprintf(fs, "%s->%s;\n", o.ID, child.ID)
|
|
}
|
|
return nil
|
|
})
|
|
fmt.Fprintln(fs, "}")
|
|
}
|