Skip to content

Commit a30e6a1

Browse files
fix(json): add YAMLToJSONCompatibleGoType, tests, and fix YAML merge keys
1 parent 903dfce commit a30e6a1

File tree

3 files changed

+487
-5
lines changed

3 files changed

+487
-5
lines changed

json/json.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ func YAMLToJSON(node *yaml.Node, indentation int, buffer io.Writer) error {
2626
return e.Encode(v)
2727
}
2828

29+
// YAMLToJSONCompatibleGoType will convert the provided YAML node to a compatible Go type ready for json marshalling in a stable way not reordering keys.
30+
// Provided to allow a custom JSON marshalling implementation to be used.
31+
func YAMLToJSONCompatibleGoType(node *yaml.Node) (any, error) {
32+
v, err := handleYAMLNode(node)
33+
if err != nil {
34+
return nil, err
35+
}
36+
37+
return v, nil
38+
}
39+
2940
func handleYAMLNode(node *yaml.Node) (any, error) {
3041
if node == nil {
3142
return nil, nil
@@ -67,12 +78,33 @@ func handleMappingNode(node *yaml.Node) (any, error) {
6778
kv = string(keyData)
6879
}
6980

81+
keyStr := fmt.Sprintf("%v", kv)
82+
83+
// Handle YAML merge key (<<)
84+
if keyStr == "<<" {
85+
vv, err := handleYAMLNode(n)
86+
if err != nil {
87+
return nil, err
88+
}
89+
90+
// Merge the values from the referenced map
91+
if mergeMap, ok := vv.(*sequencedmap.Map[string, any]); ok {
92+
for mergeKey, mergeValue := range mergeMap.All() {
93+
// Only set if the key doesn't already exist (merge keys have lower priority)
94+
if !v.Has(mergeKey) {
95+
v.Set(mergeKey, mergeValue)
96+
}
97+
}
98+
}
99+
continue
100+
}
101+
70102
vv, err := handleYAMLNode(n)
71103
if err != nil {
72104
return nil, err
73105
}
74106

75-
v.Set(fmt.Sprintf("%v", kv), vv)
107+
v.Set(keyStr, vv)
76108
}
77109

78110
return v, nil

0 commit comments

Comments
 (0)