mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 20:47:49 +00:00
90 lines
1.8 KiB
Go
90 lines
1.8 KiB
Go
package json
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"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
|
|
//
|
|
// NOTE: The limitation is this won't work with YAML that is not compatible with JSON, ie yaml with anchors or complex map keys
|
|
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:
|
|
panic("currently unsupported")
|
|
default:
|
|
return nil, fmt.Errorf("unknown node kind: %v", node.Kind)
|
|
}
|
|
}
|
|
|
|
func handleMappingNode(node *yaml.Node) (any, error) {
|
|
m := orderedmap.New[string, yaml.Node]()
|
|
|
|
if err := node.Decode(m); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
v := orderedmap.New[string, any]()
|
|
for pair := orderedmap.First(m); pair != nil; pair = pair.Next() {
|
|
n := pair.Value()
|
|
vv, err := handleYAMLNode(&n)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
v.Set(pair.Key(), 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
|
|
}
|