cue: support optional fields for FillPath
Change-Id: I44addd5905d193e80c4c0924a1c300dac51c1a58
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9527
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Paul Jolly <paul@myitcv.org.uk>
diff --git a/cue/types.go b/cue/types.go
index 641bd9c..9e7aa70 100644
--- a/cue/types.go
+++ b/cue/types.go
@@ -1590,7 +1590,6 @@
// Any reference in v referring to the value at the given path will resolve to x
// in the newly created value. The resulting value is not validated.
//
-// List paths are not supported at this time.
func (v Value) FillPath(p Path, x interface{}) Value {
if v.v == nil {
// TODO: panic here?
@@ -1616,9 +1615,26 @@
expr = convert.GoValueToValue(ctx, x, true)
}
for i := len(p.path) - 1; i >= 0; i-- {
- switch sel := p.path[i]; {
- case sel.sel.kind() == adt.IntLabel:
- i := sel.sel.feature(ctx.Runtime).Index()
+ switch sel := p.path[i].sel; {
+ case sel == AnyString.sel:
+ expr = &adt.StructLit{Decls: []adt.Decl{
+ &adt.BulkOptionalField{
+ Filter: &adt.BasicType{K: adt.StringKind},
+ Value: expr,
+ },
+ }}
+
+ case sel == anyIndex.sel:
+ expr = &adt.ListLit{Elems: []adt.Elem{
+ &adt.Ellipsis{Value: expr},
+ }}
+
+ case sel == anyDefinition.sel:
+ expr = &adt.Bottom{Err: errors.Newf(token.NoPos,
+ "AnyDefinition not supported")}
+
+ case sel.kind() == adt.IntLabel:
+ i := sel.feature(ctx.Runtime).Index()
list := &adt.ListLit{}
any := &adt.Top{}
// TODO(perf): make this a constant thing. This will be possible with the query extension.
@@ -1629,12 +1645,19 @@
expr = list
default:
- expr = &adt.StructLit{Decls: []adt.Decl{
- &adt.Field{
- Label: p.path[i].sel.feature(v.idx),
+ var d adt.Decl
+ if sel.optional() {
+ d = &adt.OptionalField{
+ Label: sel.feature(v.idx),
Value: expr,
- },
- }}
+ }
+ } else {
+ d = &adt.Field{
+ Label: sel.feature(v.idx),
+ Value: expr,
+ }
+ }
+ expr = &adt.StructLit{Decls: []adt.Decl{d}}
}
}
n := &adt.Vertex{}
diff --git a/cue/types_test.go b/cue/types_test.go
index 27c2339..1751b94 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -1139,6 +1139,44 @@
x: 1,
path: ParsePath("0"),
out: `[1]`,
+ }, {
+ in: `[1, ...int]`,
+ x: 1,
+ path: ParsePath("1"),
+ out: `[1, 1]`,
+ }, {
+ in: `a: {b: v: int, c: v: int}`,
+ x: 1,
+ path: MakePath(Str("a"), AnyString, Str("v")),
+ out: `{
+ a: {
+ b: {
+ v: 1
+ }
+ c: {
+ v: 1
+ }
+ }
+}`,
+ }, {
+ in: `a: [_]`,
+ x: 1,
+ path: MakePath(Str("a"), AnyIndex, Str("b")),
+ out: `{
+ a: [{
+ b: 1
+ }]
+}`,
+ }, {
+ in: `a: 1`,
+ x: 1,
+ path: MakePath(Str("b").Optional()),
+ out: `{a: 1}`,
+ }, {
+ in: `b: int`,
+ x: 1,
+ path: MakePath(Str("b").Optional()),
+ out: `{b: 1}`,
}}
for _, tc := range testCases {