-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
depth.go
92 lines (73 loc) · 1.46 KB
/
depth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package structural
import (
"fmt"
"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"github.com/hofstadter-io/cuetils/cmd/cuetils/flags"
)
type DepthResult struct {
Filename string
Depth int
}
func DepthGlobs(globs []string, opts *flags.RootPflagpole) ([]DepthResult, error) {
// no globs, then stdin
if len(globs) == 0 {
globs = []string{"-"}
}
inputs, err := LoadGlobs(globs)
if err != nil {
return nil, err
}
if len(inputs) == 0 {
return nil, fmt.Errorf("no matches found")
}
ctx := cuecontext.New()
depths := make([]DepthResult, 0)
for _, input := range inputs {
// need to handle encodings here?
iv := ctx.CompileBytes(input.Content, cue.Filename(input.Filename))
if iv.Err() != nil {
return nil, iv.Err()
}
d := depth(iv)
depths = append(depths, DepthResult{
Filename: input.Filename,
Depth: int(d),
})
}
return depths, nil
}
func DepthValue(val cue.Value) int {
return depth(val)
}
func depth(val cue.Value) int {
var max, curr int
// increase curr, check against max
before := func(v cue.Value) bool {
switch v.IncompleteKind() {
case cue.StructKind:
curr += 1
case cue.ListKind:
// nothing
default:
curr += 1
}
if curr > max {
max = curr
}
return true
}
// decrease curr after
after := func(v cue.Value) {
switch v.IncompleteKind() {
case cue.StructKind:
curr -= 1
case cue.ListKind:
// nothing
default:
curr -= 1
}
}
Walk(val, before, after)
return max
}