github.com/tomwright/dasel@v1.27.3/output_formatter.go (about) 1 package dasel 2 3 import ( 4 "bytes" 5 "github.com/Masterminds/sprig/v3" 6 "text/template" 7 ) 8 9 // FormatNode formats a node with the format template and returns the result. 10 func FormatNode(node *Node, format string) (*bytes.Buffer, error) { 11 tpl, err := formatNodeTemplate( 12 &templateNode{ 13 Node: node, 14 isFirst: true, 15 isLast: true, 16 }, 17 ).Parse(format) 18 if err != nil { 19 return nil, err 20 } 21 22 buf := new(bytes.Buffer) 23 24 err = tpl.Execute(buf, node.InterfaceValue()) 25 return buf, err 26 } 27 28 type templateNode struct { 29 *Node 30 31 isFirst bool 32 isLast bool 33 } 34 35 // FormatNodes formats a slice of nodes with the format template and returns the result. 36 func FormatNodes(nodes []*Node, format string) (*bytes.Buffer, error) { 37 buf := new(bytes.Buffer) 38 nodesLen := len(nodes) 39 for k, node := range nodes { 40 tpl, err := formatNodeTemplate( 41 &templateNode{ 42 Node: node, 43 isFirst: k == 0, 44 isLast: k == (nodesLen - 1), 45 }, 46 ).Parse(format) 47 if err != nil { 48 return nil, err 49 } 50 51 if err := tpl.Execute(buf, node.InterfaceValue()); err != nil { 52 return nil, err 53 } 54 } 55 return buf, nil 56 } 57 58 type formatTemplateFuncs struct { 59 node *templateNode 60 } 61 62 func (funcs *formatTemplateFuncs) funcMap() template.FuncMap { 63 return template.FuncMap{ 64 "query": funcs.query, 65 "queryMultiple": funcs.queryMultiple, 66 "select": funcs.query, 67 "selectMultiple": funcs.queryMultiple, 68 "format": funcs.format, 69 "isFirst": funcs.isFirst, 70 "isLast": funcs.isLast, 71 "newline": funcs.newline, 72 } 73 } 74 75 func (funcs *formatTemplateFuncs) newline() string { 76 return "\n" 77 } 78 79 func (funcs *formatTemplateFuncs) isFirst() bool { 80 return funcs.node.isFirst 81 } 82 83 func (funcs *formatTemplateFuncs) isLast() bool { 84 return funcs.node.isLast 85 } 86 87 func (funcs *formatTemplateFuncs) query(selector string) *Node { 88 res, err := funcs.node.Query(selector) 89 if err != nil { 90 return nil 91 } 92 return res 93 } 94 95 func (funcs *formatTemplateFuncs) queryMultiple(selector string) []*Node { 96 res, err := funcs.node.QueryMultiple(selector) 97 if err != nil { 98 return nil 99 } 100 return res 101 } 102 103 func (funcs *formatTemplateFuncs) format(format string, target interface{}) string { 104 switch t := target.(type) { 105 case []*Node: 106 buf, err := FormatNodes(t, format) 107 if err != nil { 108 return err.Error() 109 } 110 res := buf.String() 111 return res 112 case *Node: 113 buf, err := FormatNode(t, format) 114 if err != nil { 115 return err.Error() 116 } 117 return buf.String() 118 } 119 120 return "<nil>" 121 } 122 123 func formatNodeTemplate(node *templateNode) *template.Template { 124 funcs := &formatTemplateFuncs{ 125 node: node, 126 } 127 return template. 128 New("nodeFormat"). 129 Funcs(sprig.TxtFuncMap()). 130 Funcs(funcs.funcMap()) 131 }