Skip to content

Commit

Permalink
cue: support optional fields for FillPath
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
mpvl committed Apr 29, 2021
1 parent ac7e992 commit 2e1ac0f
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 9 deletions.
41 changes: 32 additions & 9 deletions cue/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1590,7 +1590,6 @@ func (v hiddenValue) Fill(x interface{}, path ...string) Value {
// 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?
Expand All @@ -1616,9 +1615,26 @@ func (v Value) FillPath(p Path, x interface{}) Value {
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.
Expand All @@ -1629,12 +1645,19 @@ func (v Value) FillPath(p Path, x interface{}) Value {
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{}
Expand Down
38 changes: 38 additions & 0 deletions cue/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,44 @@ func TestFillPath(t *testing.T) {
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 {
Expand Down

0 comments on commit 2e1ac0f

Please sign in to comment.