Support multiple $merge in a list

This commit is contained in:
Ian Gulliver
2024-10-13 11:27:33 -07:00
parent 400ac50581
commit 0554560f9f
7 changed files with 51 additions and 18 deletions

View File

@@ -91,7 +91,7 @@ func mergeMapMap(dst map[string]any, src map[string]any) (map[string]any, error)
return dst, nil
}
func mergeList(dst []any, src any) (any, error) {
func mergeList(dst []any, src any) ([]any, error) {
switch src2 := src.(type) {
case []any:
return mergeListList(dst, src2)
@@ -171,7 +171,6 @@ func mergeListDelete(obj []any, del any) ([]any, error) {
return []any{v}, nil
})
if err != nil {
return nil, err
}

View File

@@ -44,6 +44,7 @@ import (
// Phase 5
// - $""
// - $encode
// - $decode
// - $env
// - $repeat
// - $value

View File

@@ -82,16 +82,35 @@ func process1MapReplace(obj map[string]any, mergeFrom *Document, mergeFromDocs [
}
func process1List(obj []any, mergeFrom *Document, mergeFromDocs []*Document, depth int) (any, error) {
m, obj, err := popListMapValue(obj, "$merge")
if err != nil {
return nil, err
merge := []any{}
obj, err := filterList(obj, func(v any) ([]any, error) {
v2, ok := v.(map[string]any)
if !ok {
return []any{v}, nil
}
if len(v2) != 1 {
return []any{v}, nil
}
found, val, v2 := popMapValue(v2, "$merge")
if found {
merge = append(merge, val)
return nil, nil
}
return []any{v2}, nil
})
for _, m := range merge {
obj, err = process1ListMerge(obj, mergeFrom, mergeFromDocs, m, depth)
if err != nil {
return nil, err
}
}
if m != nil {
return process1ListMerge(obj, mergeFrom, mergeFromDocs, m, depth)
}
m, obj, err = popListMapValue(obj, "$replace")
m, obj, err := popListMapValue(obj, "$replace")
if err != nil {
return nil, err
}
@@ -114,18 +133,13 @@ func process1List(obj []any, mergeFrom *Document, mergeFromDocs []*Document, dep
})
}
func process1ListMerge(obj []any, mergeFrom *Document, mergeFromDocs []*Document, m any, depth int) (any, error) {
func process1ListMerge(obj []any, mergeFrom *Document, mergeFromDocs []*Document, m any, depth int) ([]any, error) {
in, err := get(mergeFrom, mergeFromDocs, m)
if err != nil {
return nil, err
}
next, err := mergeList(obj, in)
if err != nil {
return nil, err
}
return process1(next, mergeFrom, mergeFromDocs, depth)
return mergeList(obj, in)
}
func process1ListReplace(obj []any, mergeFrom *Document, mergeFromDocs []*Document, m any, depth int) (any, error) {

View File

@@ -236,7 +236,7 @@ func process2DecodeString(obj any, mergeFrom *Document, mergeFromDocs []*Documen
func process2DecodeStringMap(obj map[string]any, mergeFrom *Document, mergeFromDocs []*Document, v string, depth int) (any, error) {
found, val, obj := popMapValue(obj, "$value")
if !found {
return nil, fmt.Errorf("$decode: missing $value in %#v (#w)", obj, ErrInvalidType)
return nil, fmt.Errorf("$decode: missing $value in %#v (%w)", obj, ErrInvalidType)
}
val2, ok := val.(string)

View File

@@ -0,0 +1,9 @@
foo:
bar:
- a: 1
zag:
- c: 3
zig:
- b: 2
- $merge: foo.zag
- $merge: foo.bar

View File

@@ -0,0 +1 @@
bkl a.yaml

View File

@@ -0,0 +1,9 @@
foo:
bar:
- a: 1
zag:
- c: 3
zig:
- b: 2
- c: 3
- a: 1