@@ -15,6 +15,22 @@ type FieldName string
1515// Used to represent an arbitrary field name
1616const FieldNameAny FieldName = ""
1717
18+ type FieldPath []FieldName
19+
20+ func (path FieldPath ) String () string {
21+ var parts []string
22+
23+ for _ , part := range path {
24+ if part == FieldNameAny {
25+ parts = append (parts , "<any>" )
26+ } else {
27+ parts = append (parts , string (part ))
28+ }
29+ }
30+
31+ return strings .Join (parts , "." )
32+ }
33+
1834// The FieldConfiguration struct represents how boolean expression
1935// validation and preparation should work for the given field. A field
2036// in this case is a single element of a selector.
@@ -312,3 +328,25 @@ func (configs FieldConfigurations) String() string {
312328 configs .stringInternal (& builder , 0 , "" )
313329 return builder .String ()
314330}
331+
332+ type FieldConfigurationWalkFn func (path FieldPath , config * FieldConfiguration ) bool
333+
334+ func (configs FieldConfigurations ) walk (path FieldPath , walkFn FieldConfigurationWalkFn ) bool {
335+ for fieldName , fieldConfig := range configs {
336+ newPath := append (path , fieldName )
337+
338+ if ! walkFn (newPath , fieldConfig ) {
339+ return false
340+ }
341+
342+ if ! fieldConfig .SubFields .walk (newPath , walkFn ) {
343+ return false
344+ }
345+ }
346+
347+ return true
348+ }
349+
350+ func (configs FieldConfigurations ) Walk (walkFn FieldConfigurationWalkFn ) bool {
351+ return configs .walk (nil , walkFn )
352+ }
0 commit comments