-
Notifications
You must be signed in to change notification settings - Fork 70
/
json.go
117 lines (98 loc) · 2.28 KB
/
json.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package format
import (
"bytes"
"encoding/json"
"fmt"
"strings"
"github.com/aws-cloudformation/rain/cft/parse"
"github.com/aws-cloudformation/rain/internal/config"
"gopkg.in/yaml.v3"
)
func handleScalar(node *yaml.Node) interface{} {
if node.Tag != "" && !strings.HasPrefix(node.Tag, "!!") {
// Convert back to map style
tag := strings.TrimPrefix(node.Tag, "!")
if tag != "Ref" {
tag = "Fn::" + tag
}
return MapSlice{
MapItem{
Key: tag,
Value: node.Value,
},
}
}
// Marshal and unmarshal the node and return the result
intermediate, err := yaml.Marshal(node)
if err != nil {
panic(err)
}
config.Debugf("intermediate: %v", string(intermediate))
var out interface{}
err = yaml.Unmarshal(intermediate, &out)
if err != nil {
panic(err)
}
return out
}
func Jsonise(node *yaml.Node) interface{} {
switch node.Kind {
case yaml.DocumentNode:
return Jsonise(node.Content[0])
case yaml.MappingNode:
out := make(MapSlice, len(node.Content)/2)
for i := 0; i < len(node.Content); i += 2 {
key, value := node.Content[i], node.Content[i+1]
out[i/2] = MapItem{
Key: Jsonise(key),
Value: Jsonise(value),
}
}
return out
case yaml.SequenceNode:
out := make([]interface{}, len(node.Content))
for i, n := range node.Content {
out[i] = Jsonise(n)
}
return out
default:
return handleScalar(node)
}
}
func convertToJSON(in string) string {
config.Debugf("convertToJson: %v", in)
var d yaml.Node
err := yaml.Unmarshal([]byte(in), &d)
if err != nil {
panic(err)
}
err = parse.NormalizeNode(&d)
if err != nil {
panic(err)
}
intermediate := Jsonise(&d)
out, err := ToJson(intermediate, " ")
if err != nil {
panic(err)
}
s := string(out)
return s
}
// converts struct to a JSON formatted string
func PrettyPrint(i interface{}) string {
s, _ := ToJson(i, "\t")
return string(s)
}
// ToJson overrides the default behavior of json.Marshal to leave < > alone
func ToJson(i interface{}, indent string) ([]byte, error) {
si := fmt.Sprintf("%#v", i)
config.Debugf("ToJson(%s)", si)
buf := &bytes.Buffer{}
enc := json.NewEncoder(buf)
enc.SetEscapeHTML(false)
enc.SetIndent("", indent)
err := enc.Encode(i)
retval := bytes.TrimRight(buf.Bytes(), "\n")
config.Debugf("ToJson retval: %s", retval)
return retval, err
}