feat: renderer
This commit is contained in:
83
renderer/codec/yaml.go
Normal file
83
renderer/codec/yaml.go
Normal file
@@ -0,0 +1,83 @@
|
||||
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
|
||||
}
|
Reference in New Issue
Block a user