mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 12:37:49 +00:00
99 lines
1.8 KiB
Go
99 lines
1.8 KiB
Go
package json
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"reflect"
|
|
|
|
"github.com/pb33f/libopenapi/orderedmap"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
// YAMLNodeToJSON converts yaml/json stored in a yaml.Node to json ordered matching the original yaml/json
|
|
func YAMLNodeToJSON(node *yaml.Node, indentation string) ([]byte, error) {
|
|
v, err := handleYAMLNode(node)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return json.MarshalIndent(v, "", indentation)
|
|
}
|
|
|
|
func handleYAMLNode(node *yaml.Node) (any, error) {
|
|
switch node.Kind {
|
|
case yaml.DocumentNode:
|
|
return handleYAMLNode(node.Content[0])
|
|
case yaml.SequenceNode:
|
|
return handleSequenceNode(node)
|
|
case yaml.MappingNode:
|
|
return handleMappingNode(node)
|
|
case yaml.ScalarNode:
|
|
return handleScalarNode(node)
|
|
case yaml.AliasNode:
|
|
return handleYAMLNode(node.Alias)
|
|
default:
|
|
return nil, fmt.Errorf("unknown node kind: %v", node.Kind)
|
|
}
|
|
}
|
|
|
|
func handleMappingNode(node *yaml.Node) (any, error) {
|
|
v := orderedmap.New[string, any]()
|
|
for i, n := range node.Content {
|
|
if i%2 == 0 {
|
|
continue
|
|
}
|
|
keyNode := node.Content[i-1]
|
|
kv, err := handleYAMLNode(keyNode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if reflect.TypeOf(kv).Kind() != reflect.String {
|
|
keyData, err := json.Marshal(kv)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
kv = string(keyData)
|
|
}
|
|
|
|
vv, err := handleYAMLNode(n)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
v.Set(fmt.Sprintf("%v", kv), vv)
|
|
}
|
|
|
|
return v, nil
|
|
}
|
|
|
|
func handleSequenceNode(node *yaml.Node) (any, error) {
|
|
var s []yaml.Node
|
|
|
|
if err := node.Decode(&s); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
v := make([]any, len(s))
|
|
for i, n := range s {
|
|
vv, err := handleYAMLNode(&n)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
v[i] = vv
|
|
}
|
|
|
|
return v, nil
|
|
}
|
|
|
|
func handleScalarNode(node *yaml.Node) (any, error) {
|
|
var v any
|
|
|
|
if err := node.Decode(&v); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return v, nil
|
|
}
|