cue: add IsClosed method
Change-Id: I2303819226b0fe2ee692e2e1abccf938a5de955a
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5400
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/types.go b/cue/types.go
index b37631f..6ef9b5c 100644
--- a/cue/types.go
+++ b/cue/types.go
@@ -984,6 +984,24 @@
// TODO: IsFinal: this value can never be changed.
+// IsClosed reports whether a list of struct is closed. It reports false when
+// when the value is not a list or struct.
+func (v Value) IsClosed() bool {
+ switch v.Kind() {
+ case StructKind:
+ if st, ok := v.path.val().(*structLit); ok {
+ return st.closeStatus.shouldClose()
+ }
+ case ListKind:
+ if l, ok := v.path.val().(*list); ok {
+ if n, ok := l.len.(*numLit); ok {
+ return n.intValue(v.ctx()) == len(l.elem.arcs)
+ }
+ }
+ }
+ return false
+}
+
// IsConcrete reports whether the current value is a concrete scalar value
// (not relying on default values), a terminal error, a list, or a struct.
// It does not verify that values of lists or structs are concrete themselves.
diff --git a/cue/types_test.go b/cue/types_test.go
index 4a9611e..aa4da04 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -50,6 +50,7 @@
json string
valid bool
concrete bool
+ closed bool
// pos token.Pos
}{{ // Not a concrete value.
value: `v: _`,
@@ -152,10 +153,17 @@
incompleteKind: StructKind,
concrete: true,
}, {
+ value: `v: close({})`,
+ kind: StructKind,
+ incompleteKind: StructKind,
+ concrete: true,
+ closed: true,
+ }, {
value: `v: []`,
kind: ListKind,
incompleteKind: ListKind,
concrete: true,
+ closed: true,
}, {
value: `v: {a: int, b: [1][a]}.b`,
kind: BottomKind,
@@ -199,6 +207,9 @@
if got := v.IsConcrete(); got != tc.concrete {
t.Errorf("IsConcrete: got %v; want %v", got, tc.concrete)
}
+ if got := v.IsClosed(); got != tc.closed {
+ t.Errorf("IsClosed: got %v; want %v", got, tc.closed)
+ }
})
}
}
diff --git a/cue/value.go b/cue/value.go
index 3ba7d65..52abfd1 100644
--- a/cue/value.go
+++ b/cue/value.go
@@ -397,7 +397,6 @@
func (x *numLit) intValue(ctx *context) int {
v, err := x.v.Int64()
if err != nil {
- ctx.mkErr(x, "intValue: %v", err)
return 0
}
return int(v)