Evaluate $output: false after $merge/$replace

This commit is contained in:
Ian Gulliver
2023-08-01 20:36:41 -07:00
parent c9ae8c4d25
commit 91b8dfab3c
7 changed files with 93 additions and 16 deletions

View File

@@ -5,12 +5,12 @@ import (
)
func findOutputs(obj any) (any, []any, error) {
switch objType := obj.(type) {
switch obj2 := obj.(type) {
case map[string]any:
return findOutputsMap(objType)
return findOutputsMap(obj2)
case []any:
return findOutputsList(objType)
return findOutputsList(obj2)
default:
return obj, []any{}, nil
@@ -69,3 +69,60 @@ func findOutputsList(obj []any) (any, []any, error) {
return ret, outs, nil
}
func filterOutput(obj any) (any, error) {
switch obj2 := obj.(type) {
case map[string]any:
return filterOutputMap(obj2)
case []any:
return filterOutputList(obj2)
default:
return obj, nil
}
}
func filterOutputMap(obj map[string]any) (any, error) {
output, obj := popMapBoolValue(obj, "$output", false)
if output {
return nil, nil
}
return filterMap(obj, func(k string, v any) (map[string]any, error) {
v2, err := filterOutput(v)
if err != nil {
return nil, err
}
if v2 == nil {
return nil, nil
}
return map[string]any{k: v2}, nil
})
}
func filterOutputList(obj []any) (any, error) {
output, obj, err := popListMapBoolValue(obj, "$output", false)
if err != nil {
return nil, err
}
if output {
return nil, nil
}
return filterList(obj, func(v any) ([]any, error) {
v2, err := filterOutput(v)
if err != nil {
return nil, err
}
if v2 == nil {
return nil, nil
}
return []any{v2}, nil
})
}

View File

@@ -39,12 +39,12 @@ import (
//
// Output phase 1 (process)
// - $merge
// - $replace: map
// - $replace: string
// - $output: false
// - $encode
//
// Output phase 2 (output)
// - $output: true
// - $output
type Parser struct {
docs []any
debug bool
@@ -240,7 +240,24 @@ func (p *Parser) OutputDocumentsIndex(index int) ([]any, error) {
outs = append(outs, obj)
}
err = validate(obj)
outs, err = filterList(outs, func(v any) ([]any, error) {
v2, err := filterOutput(v)
if err != nil {
return nil, err
}
if v2 == nil {
return nil, nil
}
err = validate(v2)
if err != nil {
return nil, err
}
return []any{v2}, nil
})
if err != nil {
return nil, err
}

View File

@@ -44,11 +44,6 @@ func processMap(obj map[string]any, mergeFrom any, mergeFromDocs []any, depth in
return processMapReplace(mergeFrom, mergeFromDocs, m, depth)
}
output, found := getMapBoolValue(obj, "$output")
if found && !output {
return nil, nil
}
encode := getMapStringValue(obj, "$encode")
if encode != "" {
delete(obj, "$encode")
@@ -138,10 +133,6 @@ func processList(obj []any, mergeFrom any, mergeFromDocs []any, depth int) (any,
return processListReplace(mergeFrom, mergeFromDocs, m, depth)
}
if hasListMapBoolValue(obj, "$output", false) {
return nil, nil
}
encode, obj, err := popListMapStringValue(obj, "$encode")
if err != nil {
return nil, err

View File

@@ -0,0 +1,5 @@
a:
b: 2
$output: false
c:
$replace: a.b

View File

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

View File

@@ -0,0 +1 @@
c: 2

View File

@@ -233,7 +233,12 @@ func popListMapStringValue(l []any, k string) (string, []any, error) {
func filterMap(m map[string]any, filter func(string, any) (map[string]any, error)) (map[string]any, error) {
ret := map[string]any{}
for k, v := range m {
ks := polyfill.MapsKeys(m)
polyfill.SlicesSort(ks)
for _, k := range ks {
v := m[k]
m2, err := filter(k, v)
if err != nil {
return nil, err