functions: Improve marks support for length
Similar to cty's implementation, we only need to preserve marks from the value itself, not any nested values it may contain. This means that taking the length of an umarked list with marked elements results in an unmarked number.
This commit is contained in:
parent
8d4d333efe
commit
e0c6b3fcda
|
@ -20,6 +20,7 @@ var LengthFunc = function.New(&function.Spec{
|
|||
Type: cty.DynamicPseudoType,
|
||||
AllowDynamicType: true,
|
||||
AllowUnknown: true,
|
||||
AllowMarked: true,
|
||||
},
|
||||
},
|
||||
Type: func(args []cty.Value) (cty.Type, error) {
|
||||
|
@ -34,15 +35,16 @@ var LengthFunc = function.New(&function.Spec{
|
|||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
coll := args[0]
|
||||
collTy := args[0].Type()
|
||||
marks := coll.Marks()
|
||||
switch {
|
||||
case collTy == cty.DynamicPseudoType:
|
||||
return cty.UnknownVal(cty.Number), nil
|
||||
return cty.UnknownVal(cty.Number).WithMarks(marks), nil
|
||||
case collTy.IsTupleType():
|
||||
l := len(collTy.TupleElementTypes())
|
||||
return cty.NumberIntVal(int64(l)), nil
|
||||
return cty.NumberIntVal(int64(l)).WithMarks(marks), nil
|
||||
case collTy.IsObjectType():
|
||||
l := len(collTy.AttributeTypes())
|
||||
return cty.NumberIntVal(int64(l)), nil
|
||||
return cty.NumberIntVal(int64(l)).WithMarks(marks), nil
|
||||
case collTy == cty.String:
|
||||
// We'll delegate to the cty stdlib strlen function here, because
|
||||
// it deals with all of the complexities of tokenizing unicode
|
||||
|
|
|
@ -122,6 +122,54 @@ func TestLength(t *testing.T) {
|
|||
cty.DynamicVal,
|
||||
cty.UnknownVal(cty.Number),
|
||||
},
|
||||
{ // Marked collections return a marked length
|
||||
cty.ListVal([]cty.Value{
|
||||
cty.StringVal("hello"),
|
||||
cty.StringVal("world"),
|
||||
}).Mark("secret"),
|
||||
cty.NumberIntVal(2).Mark("secret"),
|
||||
},
|
||||
{ // Marks on values in unmarked collections do not propagate
|
||||
cty.ListVal([]cty.Value{
|
||||
cty.StringVal("hello").Mark("a"),
|
||||
cty.StringVal("world").Mark("b"),
|
||||
}),
|
||||
cty.NumberIntVal(2),
|
||||
},
|
||||
{ // Marked strings return a marked length
|
||||
cty.StringVal("hello world").Mark("secret"),
|
||||
cty.NumberIntVal(11).Mark("secret"),
|
||||
},
|
||||
{ // Marked tuples return a marked length
|
||||
cty.TupleVal([]cty.Value{
|
||||
cty.StringVal("hello"),
|
||||
cty.StringVal("world"),
|
||||
}).Mark("secret"),
|
||||
cty.NumberIntVal(2).Mark("secret"),
|
||||
},
|
||||
{ // Marks on values in unmarked tuples do not propagate
|
||||
cty.TupleVal([]cty.Value{
|
||||
cty.StringVal("hello").Mark("a"),
|
||||
cty.StringVal("world").Mark("b"),
|
||||
}),
|
||||
cty.NumberIntVal(2),
|
||||
},
|
||||
{ // Marked objects return a marked length
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"a": cty.StringVal("hello"),
|
||||
"b": cty.StringVal("world"),
|
||||
"c": cty.StringVal("nice to meet you"),
|
||||
}).Mark("secret"),
|
||||
cty.NumberIntVal(3).Mark("secret"),
|
||||
},
|
||||
{ // Marks on object attribute values do not propagate
|
||||
cty.ObjectVal(map[string]cty.Value{
|
||||
"a": cty.StringVal("hello").Mark("a"),
|
||||
"b": cty.StringVal("world").Mark("b"),
|
||||
"c": cty.StringVal("nice to meet you").Mark("c"),
|
||||
}),
|
||||
cty.NumberIntVal(3),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
Loading…
Reference in New Issue