1
0
mirror of https://github.com/TomWright/dasel.git synced 2022-05-22 02:32:45 +03:00
Files
dasel-data-selector/output_formatter.go

130 lines
2.6 KiB
Go

package dasel
import (
"bytes"
"text/template"
)
// FormatNode formats a node with the format template and returns the result.
func FormatNode(node *Node, format string) (*bytes.Buffer, error) {
tpl, err := formatNodeTemplate(
&templateNode{
Node: node,
isFirst: true,
isLast: true,
},
).Parse(format)
if err != nil {
return nil, err
}
buf := new(bytes.Buffer)
err = tpl.Execute(buf, node.InterfaceValue())
return buf, err
}
type templateNode struct {
*Node
isFirst bool
isLast bool
}
// FormatNodes formats a slice of nodes with the format template and returns the result.
func FormatNodes(nodes []*Node, format string) (*bytes.Buffer, error) {
buf := new(bytes.Buffer)
nodesLen := len(nodes)
for k, node := range nodes {
tpl, err := formatNodeTemplate(
&templateNode{
Node: node,
isFirst: k == 0,
isLast: k == (nodesLen - 1),
},
).Parse(format)
if err != nil {
return nil, err
}
if err := tpl.Execute(buf, node.InterfaceValue()); err != nil {
return nil, err
}
}
return buf, nil
}
type formatTemplateFuncs struct {
node *templateNode
}
func (funcs *formatTemplateFuncs) funcMap() template.FuncMap {
return template.FuncMap{
"query": funcs.query,
"queryMultiple": funcs.queryMultiple,
"select": funcs.query,
"selectMultiple": funcs.queryMultiple,
"format": funcs.format,
"isFirst": funcs.isFirst,
"isLast": funcs.isLast,
"newline": funcs.newline,
}
}
func (funcs *formatTemplateFuncs) newline() string {
return "\n"
}
func (funcs *formatTemplateFuncs) isFirst() bool {
return funcs.node.isFirst
}
func (funcs *formatTemplateFuncs) isLast() bool {
return funcs.node.isLast
}
func (funcs *formatTemplateFuncs) query(selector string) *Node {
res, err := funcs.node.Query(selector)
if err != nil {
return nil
}
return res
}
func (funcs *formatTemplateFuncs) queryMultiple(selector string) []*Node {
res, err := funcs.node.QueryMultiple(selector)
if err != nil {
return nil
}
return res
}
func (funcs *formatTemplateFuncs) format(format string, target interface{}) string {
switch t := target.(type) {
case []*Node:
buf, err := FormatNodes(t, format)
if err != nil {
return err.Error()
}
res := buf.String()
return res
case *Node:
buf, err := FormatNode(t, format)
if err != nil {
return err.Error()
}
return buf.String()
}
return "<nil>"
}
func formatNodeTemplate(node *templateNode) *template.Template {
funcs := &formatTemplateFuncs{
node: node,
}
tpl := template.New("nodeFormat")
tpl.Funcs(funcs.funcMap())
return tpl
}