@@ -20,19 +20,26 @@ import (
2020)
2121
2222type removingWalker struct {
23- value value.Value
24- out interface {}
25- schema * schema.Schema
26- toRemove * fieldpath.Set
27- allocator value.Allocator
23+ value value.Value
24+ out interface {}
25+ schema * schema.Schema
26+ toRemove * fieldpath.Set
27+ allocator value.Allocator
28+ shouldExtract bool
2829}
2930
30- func removeItemsWithSchema (val value.Value , toRemove * fieldpath.Set , schema * schema.Schema , typeRef schema.TypeRef ) value.Value {
31+ // removeItemsWithSchema will walk the given value and look for items from the toRemove set.
32+ // Depending on whether shouldExtract is set true or false, it will return a modified version
33+ // of the input value with either:
34+ // 1. only the items in the toRemove set (when shouldExtract is true) or
35+ // 2. the items from the toRemove set removed from the value (when shouldExtract is false).
36+ func removeItemsWithSchema (val value.Value , toRemove * fieldpath.Set , schema * schema.Schema , typeRef schema.TypeRef , shouldExtract bool ) value.Value {
3137 w := & removingWalker {
32- value : val ,
33- schema : schema ,
34- toRemove : toRemove ,
35- allocator : value .NewFreelistAllocator (),
38+ value : val ,
39+ schema : schema ,
40+ toRemove : toRemove ,
41+ allocator : value .NewFreelistAllocator (),
42+ shouldExtract : shouldExtract ,
3643 }
3744 resolveSchema (schema , typeRef , val , w )
3845 return value .NewValueInterface (w .out )
@@ -59,11 +66,22 @@ func (w *removingWalker) doList(t *schema.List) (errs ValidationErrors) {
5966 // Ignore error because we have already validated this list
6067 pe , _ := listItemToPathElement (w .allocator , w .schema , t , i , item )
6168 path , _ := fieldpath .MakePath (pe )
69+ // save items on the path when we shouldExtract
70+ // but ignore them when we are removing (i.e. !w.shouldExtract)
6271 if w .toRemove .Has (path ) {
63- continue
72+ if w .shouldExtract {
73+ newItems = append (newItems , item .Unstructured ())
74+ } else {
75+ continue
76+ }
6477 }
6578 if subset := w .toRemove .WithPrefix (pe ); ! subset .Empty () {
66- item = removeItemsWithSchema (item , subset , w .schema , t .ElementType )
79+ item = removeItemsWithSchema (item , subset , w .schema , t .ElementType , w .shouldExtract )
80+ } else {
81+ // don't save items not on the path when we shouldExtract.
82+ if w .shouldExtract {
83+ continue
84+ }
6785 }
6886 newItems = append (newItems , item .Unstructured ())
6987 }
@@ -96,11 +114,21 @@ func (w *removingWalker) doMap(t *schema.Map) ValidationErrors {
96114 if ft , ok := fieldTypes [k ]; ok {
97115 fieldType = ft
98116 }
117+ // save values on the path when we shouldExtract
118+ // but ignore them when we are removing (i.e. !w.shouldExtract)
99119 if w .toRemove .Has (path ) {
120+ if w .shouldExtract {
121+ newMap [k ] = val .Unstructured ()
122+ }
100123 return true
101124 }
102125 if subset := w .toRemove .WithPrefix (pe ); ! subset .Empty () {
103- val = removeItemsWithSchema (val , subset , w .schema , fieldType )
126+ val = removeItemsWithSchema (val , subset , w .schema , fieldType , w .shouldExtract )
127+ } else {
128+ // don't save values not on the path when we shouldExtract.
129+ if w .shouldExtract {
130+ return true
131+ }
104132 }
105133 newMap [k ] = val .Unstructured ()
106134 return true
0 commit comments