84 lines
1.6 KiB
Go
84 lines
1.6 KiB
Go
package codec
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
parserUtils "git.max-richter.dev/max/marka/parser/utils"
|
|
"git.max-richter.dev/max/marka/renderer/utils"
|
|
"git.max-richter.dev/max/marka/template"
|
|
|
|
"go.yaml.in/yaml/v4"
|
|
)
|
|
|
|
func flattenInto(in map[string]any) map[string]any {
|
|
out := make(map[string]any)
|
|
|
|
var recur func(prefix string, m map[string]any)
|
|
recur = func(prefix string, m map[string]any) {
|
|
for k, v := range m {
|
|
key := k
|
|
if prefix != "" {
|
|
key = prefix + "." + k
|
|
}
|
|
|
|
switch vv := v.(type) {
|
|
case map[string]any:
|
|
if len(vv) == 1 {
|
|
recur(key, vv)
|
|
} else {
|
|
out[key] = vv
|
|
}
|
|
case map[any]any:
|
|
tmp := make(map[string]any, len(vv))
|
|
for kk, vv2 := range vv {
|
|
if ks, ok := kk.(string); ok {
|
|
tmp[ks] = vv2
|
|
}
|
|
}
|
|
if len(tmp) == 1 {
|
|
recur(key, tmp)
|
|
} else {
|
|
out[key] = tmp
|
|
}
|
|
default:
|
|
out[key] = v
|
|
}
|
|
}
|
|
}
|
|
|
|
recur("", in)
|
|
return out
|
|
}
|
|
|
|
func RenderYaml(data map[string]any, block template.Block) (string, error) {
|
|
renderedMap := make(map[string]any)
|
|
for _, field := range block.Fields {
|
|
if field.Hidden {
|
|
continue
|
|
}
|
|
|
|
var fieldValue any
|
|
var found bool
|
|
|
|
if field.CodecType == template.CodecConst {
|
|
fieldValue = field.Value
|
|
found = true
|
|
} else {
|
|
fieldValue, found = utils.GetValueFromPath(data, field.Path)
|
|
}
|
|
|
|
if found {
|
|
renderedMap = parserUtils.SetPathValue(field.Path, fieldValue, renderedMap).(map[string]any)
|
|
}
|
|
}
|
|
|
|
renderedMap = flattenInto(renderedMap)
|
|
|
|
b, err := yaml.Marshal(renderedMap)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to marshal YAML for path '%s': %w", block.Path, err)
|
|
}
|
|
return strings.TrimSuffix(string(b), "\n"), nil
|
|
}
|