There is a multi-documentary file that contains different yamls, differing in kind (k8s CRD).
I don’t like the implementation below, it seems like I’m doing unnecessary steps for decoding and type conversions.
Help me write the GetAll function more beautiful/clearer.
package main
import (
"bytes"
"fmt"
"gopkg.in/yaml.v3"
)
const yamldata = `
kind: Kind1
spec1: AAA
---
kind: Kind2
spec2: BBB
`
type Meta struct {
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
}
type Kind1 struct {
Meta `json:",inline" yaml:",inline"`
Spec1 string `json:"spec1,omitempty" yaml:"spec1,omitempty"`
}
type Kind2 struct {
Meta `json:",inline" yaml:",inline"`
Spec2 string `json:"spec2,omitempty" yaml:"spec2,omitempty"`
}
func GetAll[T Kind1 | Kind2](yamldata string) (result []*T) {
dec := yaml.NewDecoder(bytes.NewBufferString(yamldata))
for {
var node yaml.Node
err := dec.Decode(&node)
if err != nil {
return
}
var meta Meta
node.Decode(&meta)
var t T
switch any(t).(type) {
case Kind1:
if meta.Kind == "Kind1" {
var k any = &Kind1{}
rzlt, ok := k.(*T)
if ok {
node.Decode(rzlt)
result = append(result, rzlt)
}
}
case Kind2:
if meta.Kind == "Kind2" {
var k any = &Kind2{}
rzlt, ok := k.(*T)
if ok {
node.Decode(k)
result = append(result, rzlt)
}
}
}
}
}
func main() {
fmt.Print(GetAll[Kind1](yamldata)[0])
fmt.Print(GetAll[Kind2](yamldata)[0])
}