Merge pull request #1104 from hashicorp/f-nil-resource-data

helper/schema: allow pointer values to ResourceData.Set
This commit is contained in:
Mitchell Hashimoto 2015-03-03 08:59:52 -08:00
commit 1e82ccf814
2 changed files with 91 additions and 0 deletions

View File

@ -137,6 +137,25 @@ func (d *ResourceData) Partial(on bool) {
// will be returned. // will be returned.
func (d *ResourceData) Set(key string, value interface{}) error { func (d *ResourceData) Set(key string, value interface{}) error {
d.once.Do(d.init) d.once.Do(d.init)
// If the value is a pointer to a non-struct, get its value and
// use that. This allows Set to take a pointer to primitives to
// simplify the interface.
reflectVal := reflect.ValueOf(value)
if reflectVal.Kind() == reflect.Ptr {
if reflectVal.IsNil() {
// If the pointer is nil, then the value is just nil
value = nil
} else {
// Otherwise, we dereference the pointer as long as its not
// a pointer to a struct, since struct pointers are allowed.
reflectVal = reflect.Indirect(reflectVal)
if reflectVal.Kind() != reflect.Struct {
value = reflectVal.Interface()
}
}
}
return d.setWriter.WriteField(strings.Split(key, "."), value) return d.setWriter.WriteField(strings.Split(key, "."), value)
} }

View File

@ -1178,6 +1178,8 @@ func TestResourceDataHasChange(t *testing.T) {
} }
func TestResourceDataSet(t *testing.T) { func TestResourceDataSet(t *testing.T) {
var testNilPtr *string
cases := []struct { cases := []struct {
Schema map[string]*Schema Schema map[string]*Schema
State *terraform.InstanceState State *terraform.InstanceState
@ -1588,6 +1590,72 @@ func TestResourceDataSet(t *testing.T) {
GetKey: "ratios", GetKey: "ratios",
GetValue: []interface{}{1.0, 2.2, 5.5}, GetValue: []interface{}{1.0, 2.2, 5.5},
}, },
// #13: Basic pointer
{
Schema: map[string]*Schema{
"availability_zone": &Schema{
Type: TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
},
State: nil,
Diff: nil,
Key: "availability_zone",
Value: testPtrTo("foo"),
GetKey: "availability_zone",
GetValue: "foo",
},
// #14: Basic nil value
{
Schema: map[string]*Schema{
"availability_zone": &Schema{
Type: TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
},
State: nil,
Diff: nil,
Key: "availability_zone",
Value: testPtrTo(nil),
GetKey: "availability_zone",
GetValue: "",
},
// #15: Basic nil pointer
{
Schema: map[string]*Schema{
"availability_zone": &Schema{
Type: TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
},
State: nil,
Diff: nil,
Key: "availability_zone",
Value: testNilPtr,
GetKey: "availability_zone",
GetValue: "",
},
} }
for i, tc := range cases { for i, tc := range cases {
@ -2788,3 +2856,7 @@ func TestResourceDataSetId_override(t *testing.T) {
t.Fatalf("bad: %#v", actual) t.Fatalf("bad: %#v", actual)
} }
} }
func testPtrTo(raw interface{}) interface{} {
return &raw
}