yq/pkg/yqlib/encoder.go

99 lines
1.9 KiB
Go
Raw Normal View History

2020-01-10 11:01:59 +00:00
package yqlib
import (
2020-02-27 23:09:49 +00:00
"bytes"
2020-01-10 11:01:59 +00:00
"encoding/json"
"io"
yaml "gopkg.in/yaml.v3"
)
type Encoder interface {
Encode(node *yaml.Node) error
}
type yamlEncoder struct {
2020-02-27 23:09:49 +00:00
destination io.Writer
indent int
colorise bool
firstDoc bool
2020-01-10 11:01:59 +00:00
}
2020-02-27 23:09:49 +00:00
func NewYamlEncoder(destination io.Writer, indent int, colorise bool) Encoder {
2020-02-03 05:52:12 +00:00
if indent < 0 {
indent = 0
}
2020-02-27 23:09:49 +00:00
return &yamlEncoder{destination, indent, colorise, true}
2020-01-10 11:01:59 +00:00
}
func (ye *yamlEncoder) Encode(node *yaml.Node) error {
2020-02-27 23:09:49 +00:00
destination := ye.destination
tempBuffer := bytes.NewBuffer(nil)
if ye.colorise {
destination = tempBuffer
}
var encoder = yaml.NewEncoder(destination)
encoder.SetIndent(ye.indent)
// TODO: work out if the first doc had a separator or not.
if ye.firstDoc {
ye.firstDoc = false
} else if _, err := destination.Write([]byte("---\n")); err != nil {
return err
}
if err := encoder.Encode(node); err != nil {
return err
}
if ye.colorise {
return ColorizeAndPrint(tempBuffer.Bytes(), ye.destination)
}
return nil
2020-01-10 11:01:59 +00:00
}
type jsonEncoder struct {
encoder *json.Encoder
}
func mapKeysToStrings(node *yaml.Node) {
if node.Kind == yaml.MappingNode {
for index, child := range node.Content {
if index % 2 == 0 { // its a map key
child.Tag = "!!str"
}
}
}
for _, child := range node.Content {
mapKeysToStrings(child)
}
}
2020-02-03 05:52:12 +00:00
func NewJsonEncoder(destination io.Writer, prettyPrint bool, indent int) Encoder {
2020-01-10 11:01:59 +00:00
var encoder = json.NewEncoder(destination)
2020-02-03 05:52:12 +00:00
var indentString = ""
for index := 0; index < indent; index++ {
indentString = indentString + " "
}
2020-02-03 05:31:03 +00:00
if prettyPrint {
2020-02-03 05:52:12 +00:00
encoder.SetIndent("", indentString)
2020-02-03 05:31:03 +00:00
}
2020-01-10 11:01:59 +00:00
return &jsonEncoder{encoder}
}
func (je *jsonEncoder) Encode(node *yaml.Node) error {
var dataBucket interface{}
// firstly, convert all map keys to strings
mapKeysToStrings(node)
2020-01-10 11:01:59 +00:00
errorDecoding := node.Decode(&dataBucket)
if errorDecoding != nil {
return errorDecoding
}
return je.encoder.Encode(dataBucket)
}