Skip to content

Commit 2e1ac0f

Browse files
committed
cue: support optional fields for FillPath
Change-Id: I44addd5905d193e80c4c0924a1c300dac51c1a58 Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9527 Reviewed-by: CUE cueckoo <[email protected]> Reviewed-by: Paul Jolly <[email protected]>
1 parent ac7e992 commit 2e1ac0f

File tree

2 files changed

+70
-9
lines changed

2 files changed

+70
-9
lines changed

cue/types.go

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,7 +1590,6 @@ func (v hiddenValue) Fill(x interface{}, path ...string) Value {
15901590
// Any reference in v referring to the value at the given path will resolve to x
15911591
// in the newly created value. The resulting value is not validated.
15921592
//
1593-
// List paths are not supported at this time.
15941593
func (v Value) FillPath(p Path, x interface{}) Value {
15951594
if v.v == nil {
15961595
// TODO: panic here?
@@ -1616,9 +1615,26 @@ func (v Value) FillPath(p Path, x interface{}) Value {
16161615
expr = convert.GoValueToValue(ctx, x, true)
16171616
}
16181617
for i := len(p.path) - 1; i >= 0; i-- {
1619-
switch sel := p.path[i]; {
1620-
case sel.sel.kind() == adt.IntLabel:
1621-
i := sel.sel.feature(ctx.Runtime).Index()
1618+
switch sel := p.path[i].sel; {
1619+
case sel == AnyString.sel:
1620+
expr = &adt.StructLit{Decls: []adt.Decl{
1621+
&adt.BulkOptionalField{
1622+
Filter: &adt.BasicType{K: adt.StringKind},
1623+
Value: expr,
1624+
},
1625+
}}
1626+
1627+
case sel == anyIndex.sel:
1628+
expr = &adt.ListLit{Elems: []adt.Elem{
1629+
&adt.Ellipsis{Value: expr},
1630+
}}
1631+
1632+
case sel == anyDefinition.sel:
1633+
expr = &adt.Bottom{Err: errors.Newf(token.NoPos,
1634+
"AnyDefinition not supported")}
1635+
1636+
case sel.kind() == adt.IntLabel:
1637+
i := sel.feature(ctx.Runtime).Index()
16221638
list := &adt.ListLit{}
16231639
any := &adt.Top{}
16241640
// TODO(perf): make this a constant thing. This will be possible with the query extension.
@@ -1629,12 +1645,19 @@ func (v Value) FillPath(p Path, x interface{}) Value {
16291645
expr = list
16301646

16311647
default:
1632-
expr = &adt.StructLit{Decls: []adt.Decl{
1633-
&adt.Field{
1634-
Label: p.path[i].sel.feature(v.idx),
1648+
var d adt.Decl
1649+
if sel.optional() {
1650+
d = &adt.OptionalField{
1651+
Label: sel.feature(v.idx),
16351652
Value: expr,
1636-
},
1637-
}}
1653+
}
1654+
} else {
1655+
d = &adt.Field{
1656+
Label: sel.feature(v.idx),
1657+
Value: expr,
1658+
}
1659+
}
1660+
expr = &adt.StructLit{Decls: []adt.Decl{d}}
16381661
}
16391662
}
16401663
n := &adt.Vertex{}

cue/types_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,44 @@ func TestFillPath(t *testing.T) {
11391139
x: 1,
11401140
path: ParsePath("0"),
11411141
out: `[1]`,
1142+
}, {
1143+
in: `[1, ...int]`,
1144+
x: 1,
1145+
path: ParsePath("1"),
1146+
out: `[1, 1]`,
1147+
}, {
1148+
in: `a: {b: v: int, c: v: int}`,
1149+
x: 1,
1150+
path: MakePath(Str("a"), AnyString, Str("v")),
1151+
out: `{
1152+
a: {
1153+
b: {
1154+
v: 1
1155+
}
1156+
c: {
1157+
v: 1
1158+
}
1159+
}
1160+
}`,
1161+
}, {
1162+
in: `a: [_]`,
1163+
x: 1,
1164+
path: MakePath(Str("a"), AnyIndex, Str("b")),
1165+
out: `{
1166+
a: [{
1167+
b: 1
1168+
}]
1169+
}`,
1170+
}, {
1171+
in: `a: 1`,
1172+
x: 1,
1173+
path: MakePath(Str("b").Optional()),
1174+
out: `{a: 1}`,
1175+
}, {
1176+
in: `b: int`,
1177+
x: 1,
1178+
path: MakePath(Str("b").Optional()),
1179+
out: `{b: 1}`,
11421180
}}
11431181

11441182
for _, tc := range testCases {

0 commit comments

Comments
 (0)