chore: support parsing any type with `fromYaml` (#2017)
Signed-off-by: Jakob Probst <git@jakobprobst.de>
This commit is contained in:
parent
c41f3e88d2
commit
0a31423005
|
|
@ -19,7 +19,7 @@ func CastKeysToStrings(s any) (map[string]any, error) {
|
||||||
return nil, fmt.Errorf("unexpected type of key in map: expected string, got %T: value=%v, map=%v", typedK, typedK, src)
|
return nil, fmt.Errorf("unexpected type of key in map: expected string, got %T: value=%v, map=%v", typedK, typedK, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
castedV, err := recursivelyStringifyMapKey(v)
|
castedV, err := RecursivelyStringifyMapKey(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ func CastKeysToStrings(s any) (map[string]any, error) {
|
||||||
}
|
}
|
||||||
case map[string]any:
|
case map[string]any:
|
||||||
for k, v := range src {
|
for k, v := range src {
|
||||||
castedV, err := recursivelyStringifyMapKey(v)
|
castedV, err := RecursivelyStringifyMapKey(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ func CastKeysToStrings(s any) (map[string]any, error) {
|
||||||
return new, nil
|
return new, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func recursivelyStringifyMapKey(v any) (any, error) {
|
func RecursivelyStringifyMapKey(v any) (any, error) {
|
||||||
var castedV any
|
var castedV any
|
||||||
switch typedV := v.(type) {
|
switch typedV := v.(type) {
|
||||||
case map[any]any, map[string]any:
|
case map[any]any, map[string]any:
|
||||||
|
|
@ -51,7 +51,7 @@ func recursivelyStringifyMapKey(v any) (any, error) {
|
||||||
case []any:
|
case []any:
|
||||||
a := []any{}
|
a := []any{}
|
||||||
for i := range typedV {
|
for i := range typedV {
|
||||||
res, err := recursivelyStringifyMapKey(typedV[i])
|
res, err := RecursivelyStringifyMapKey(typedV[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -307,14 +307,14 @@ func ToYaml(v any) (string, error) {
|
||||||
return string(data), nil
|
return string(data), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromYaml(str string) (Values, error) {
|
func FromYaml(str string) (any, error) {
|
||||||
m := map[string]any{}
|
var m any
|
||||||
|
|
||||||
if err := yaml.Unmarshal([]byte(str), &m); err != nil {
|
if err := yaml.Unmarshal([]byte(str), &m); err != nil {
|
||||||
return nil, fmt.Errorf("%s, offending yaml: %s", err, str)
|
return nil, fmt.Errorf("%s, offending yaml: %s", err, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
m, err := maputil.CastKeysToStrings(m)
|
m, err := maputil.RecursivelyStringifyMapKey(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%s, offending yaml: %s", err, str)
|
return nil, fmt.Errorf("%s, offending yaml: %s", err, str)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,88 @@ func TestToYaml(t *testing.T) {
|
||||||
require.Equal(t, expected, actual)
|
require.Equal(t, expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testFromYaml(t *testing.T, goccyGoYaml bool, expected Values) {
|
func testFromYamlObject(t *testing.T) {
|
||||||
|
raw := `foo:
|
||||||
|
bar: BAR
|
||||||
|
`
|
||||||
|
|
||||||
|
actual, err := FromYaml(raw)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(
|
||||||
|
t,
|
||||||
|
map[string]any{
|
||||||
|
"foo": map[string]any{
|
||||||
|
"bar": "BAR",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actual,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFromYamlArray(t *testing.T) {
|
||||||
|
raw := `- foo
|
||||||
|
- bar: BAR
|
||||||
|
`
|
||||||
|
|
||||||
|
actual, err := FromYaml(raw)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(
|
||||||
|
t,
|
||||||
|
[]any{
|
||||||
|
"foo",
|
||||||
|
map[string]any{
|
||||||
|
"bar": "BAR",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actual,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFromYamlString(t *testing.T) {
|
||||||
|
raw := `foo
|
||||||
|
`
|
||||||
|
|
||||||
|
actual, err := FromYaml(raw)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "foo", actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFromYamlNumber(t *testing.T) {
|
||||||
|
raw := `1234
|
||||||
|
`
|
||||||
|
|
||||||
|
actual, err := FromYaml(raw)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
switch a := actual.(type) {
|
||||||
|
case int:
|
||||||
|
require.Equal(t, 1234, a)
|
||||||
|
case uint64:
|
||||||
|
require.Equal(t, uint64(1234), a)
|
||||||
|
default:
|
||||||
|
t.Errorf("unexpected type: %T", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFromYamlBoolean(t *testing.T) {
|
||||||
|
raw := `true
|
||||||
|
`
|
||||||
|
|
||||||
|
actual, err := FromYaml(raw)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, true, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFromYamlNull(t *testing.T) {
|
||||||
|
raw := `null
|
||||||
|
`
|
||||||
|
|
||||||
|
actual, err := FromYaml(raw)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, nil, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFromYaml(t *testing.T, goccyGoYaml bool) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
v := runtime.GoccyGoYaml
|
v := runtime.GoccyGoYaml
|
||||||
|
|
@ -209,39 +290,26 @@ func testFromYaml(t *testing.T, goccyGoYaml bool, expected Values) {
|
||||||
runtime.GoccyGoYaml = v
|
runtime.GoccyGoYaml = v
|
||||||
})
|
})
|
||||||
|
|
||||||
raw := `foo:
|
t.Run("test unmarshalling object", testFromYamlObject)
|
||||||
bar: BAR
|
|
||||||
`
|
t.Run("test unmarshalling array", testFromYamlArray)
|
||||||
actual, err := FromYaml(raw)
|
|
||||||
require.NoError(t, err)
|
t.Run("test unmarshalling string", testFromYamlString)
|
||||||
require.Equal(t, expected, actual)
|
|
||||||
|
t.Run("test unmarshalling number", testFromYamlNumber)
|
||||||
|
|
||||||
|
t.Run("test unmarshalling boolean", testFromYamlBoolean)
|
||||||
|
|
||||||
|
t.Run("test unmarshalling null", testFromYamlNull)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromYaml(t *testing.T) {
|
func TestFromYaml(t *testing.T) {
|
||||||
t.Run("with goccy/go-yaml", func(t *testing.T) {
|
t.Run("with goccy/go-yaml", func(t *testing.T) {
|
||||||
testFromYaml(
|
testFromYaml(t, true)
|
||||||
t,
|
|
||||||
true,
|
|
||||||
// nolint: unconvert
|
|
||||||
Values(map[string]any{
|
|
||||||
"foo": map[string]any{
|
|
||||||
"bar": "BAR",
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("with gopkg.in/yaml.v2", func(t *testing.T) {
|
t.Run("with gopkg.in/yaml.v2", func(t *testing.T) {
|
||||||
testFromYaml(
|
testFromYaml(t, false)
|
||||||
t,
|
|
||||||
false,
|
|
||||||
// nolint: unconvert
|
|
||||||
Values(map[string]any{
|
|
||||||
"foo": map[string]any{
|
|
||||||
"bar": "BAR",
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue