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 }