Skip to content

Commit

Permalink
convert: Strip optional attributes when creating null result values
Browse files Browse the repository at this point in the history
Object types with optional attributes are only for use as a type
conversion target and are not valid to appear in the type constraint for
a null value.
  • Loading branch information
liamcervante authored and apparentlymart committed Oct 19, 2022
1 parent 83d2f93 commit c44b63e
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 1 deletion.
8 changes: 7 additions & 1 deletion cty/convert/conversion_object.go
Expand Up @@ -80,13 +80,19 @@ func conversionObjectToObject(in, out cty.Type, unsafe bool) conversion {
}
}

if val.IsNull() {
// Strip optional attributes out of the embedded type for null
// values.
val = cty.NullVal(val.Type().WithoutOptionalAttributesDeep())
}

attrVals[name] = val
}

for name := range outOptionals {
if _, exists := attrVals[name]; !exists {
wantTy := outAtys[name]
attrVals[name] = cty.NullVal(wantTy)
attrVals[name] = cty.NullVal(wantTy.WithoutOptionalAttributesDeep())
}
}

Expand Down
97 changes: 97 additions & 0 deletions cty/convert/public_test.go
Expand Up @@ -1066,6 +1066,103 @@ func TestConvert(t *testing.T) {
}, []string{"b", "c"}),
WantError: `map element type is incompatible with attribute "c": object required`,
},
{
Value: cty.TupleVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"d": cty.NumberVal(big.NewFloat(10)),
"c": cty.ObjectVal(map[string]cty.Value{
"a": cty.StringVal("foo"),
"b": cty.BoolVal(true),
}),
}),
cty.ObjectVal(map[string]cty.Value{
"d": cty.NumberVal(big.NewFloat(5)),
"c": cty.NullVal(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
"b": cty.Bool,
}, []string{"b"})),
}),
}),
Type: cty.Set(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"c": cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
"b": cty.Bool,
}, []string{"b"}),
"d": cty.Number,
}, []string{"c"})),
Want: cty.SetVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"d": cty.NumberVal(big.NewFloat(10)),
"c": cty.ObjectVal(map[string]cty.Value{
"a": cty.StringVal("foo"),
"b": cty.BoolVal(true),
}),
}),
cty.ObjectVal(map[string]cty.Value{
"d": cty.NumberVal(big.NewFloat(5)),
"c": cty.NullVal(cty.Object(map[string]cty.Type{
"a": cty.String,
"b": cty.Bool,
})),
}),
}),
},
{
Value: cty.TupleVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"d": cty.NumberVal(big.NewFloat(10)),
"c": cty.ObjectVal(map[string]cty.Value{
"a": cty.StringVal("foo"),
"b": cty.BoolVal(true),
}),
}),
cty.ObjectVal(map[string]cty.Value{
"d": cty.NumberVal(big.NewFloat(5)),
}),
}),
Type: cty.Set(cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"c": cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
"b": cty.Bool,
}, []string{"b"}),
"d": cty.Number,
}, []string{"c"})),
Want: cty.SetVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"d": cty.NumberVal(big.NewFloat(10)),
"c": cty.ObjectVal(map[string]cty.Value{
"a": cty.StringVal("foo"),
"b": cty.BoolVal(true),
}),
}),
cty.ObjectVal(map[string]cty.Value{
"d": cty.NumberVal(big.NewFloat(5)),
"c": cty.NullVal(cty.Object(map[string]cty.Type{
"a": cty.String,
"b": cty.Bool,
})),
}),
}),
},
{
Value: cty.MapVal(map[string]cty.Value{
"a": cty.StringVal("boop"),
}),
Type: cty.ObjectWithOptionalAttrs(map[string]cty.Type{
"a": cty.String,
"b": cty.String,
"c": cty.Object(map[string]cty.Type{
"d": cty.String,
}),
}, []string{"b", "c"}),
Want: cty.ObjectVal(map[string]cty.Value{
"a": cty.StringVal("boop"),
"b": cty.NullVal(cty.String),
"c": cty.NullVal(cty.Object(map[string]cty.Type{
"d": cty.String,
})),
}),
},
{
Value: cty.ListVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
Expand Down

0 comments on commit c44b63e

Please sign in to comment.