blob: 8e3c9f9aadc4e3f9c6102cba4dabf5bf92e20bea [file] [log] [blame]
Marcel van Lohuizena32d5dd2019-12-18 21:18:29 +01001// Copyright 2019 CUE Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package walk allows walking over CUE values.
16//
17// This package replicates Value.Walk in the cue package.
18// There are several different internal uses of walk. This
19// package is intended as a single implementation that on
20// which all these implementations should converge. Once a
21// satisfactory API has been established, it can be made public.
22package walk
23
24import "cuelang.org/go/cue"
25
26// TODO:
27// - allow overriding options for descendants.
28// Perhaps func(f cue.Value) *Config?
29// - Get field information.
30
31// Alternatives:
32// type Visitor struct {}
33// func (v *Visitor) Do(cue.Value)
34// - less typing
35// - two elements are grouped together in UI.
36
37type Config struct {
38 Before func(f cue.Value) bool
39 After func(f cue.Value)
40 Opts []cue.Option
41}
42
43func Value(v cue.Value, c *Config) {
44 switch v.Kind() {
45 case cue.StructKind:
46 if c.Before != nil && !c.Before(v) {
47 return
48 }
49 iter, _ := v.Fields(c.Opts...)
50 for iter.Next() {
51 Value(iter.Value(), c)
52 }
53 case cue.ListKind:
54 if c.Before != nil && !c.Before(v) {
55 return
56 }
57 list, _ := v.List()
58 for list.Next() {
59 Value(list.Value(), c)
60 }
61 default:
62 if c.Before != nil {
63 c.Before(v)
64 }
65 }
66 if c.After != nil {
67 c.After(v)
68 }
69}