Skip to content

Commit e012b8e

Browse files
author
Paddy Carver
committed
Flesh out the As method.
The As method on tftypes.Values was essentially useless, because As is the only way to get to the underlying Go types beneath a Value, but As takes a Value as its argument, and As is the only thing you can call on a Value. So there was nothing you could actually do inside your Unmarshaler method because As only supported Unmarshalers. So As would call your Unmarshaler which could only call As which could only call your Unmarshaler and so on and so forth. This implements some basic Go type support for the canonical Go representations of all the tftypes Types, so we can get to them in our Unmarshaler methods or just use them with As directly.
1 parent 95da7fb commit e012b8e

File tree

1 file changed

+43
-5
lines changed

1 file changed

+43
-5
lines changed

tfprotov5/tftypes/value.go

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package tftypes
33
import (
44
"bytes"
55
"fmt"
6+
"math/big"
67

78
"github.com/vmihailenco/msgpack"
89
)
@@ -39,13 +40,50 @@ func NewValue(t Type, val interface{}) Value {
3940
}
4041
}
4142

42-
func (v Value) As(dst interface{}) error {
43+
func (val Value) As(dst interface{}) error {
4344
unmarshaler, ok := dst.(Unmarshaler)
44-
if !ok {
45-
// TODO: let's do unmarshaling to builtin types out of the box
46-
return fmt.Errorf("can't unmarshal into %T, needs UnmarshalTerraform5Type method", dst)
45+
if ok {
46+
return unmarshaler.UnmarshalTerraform5Type(val)
4747
}
48-
return unmarshaler.UnmarshalTerraform5Type(v)
48+
if val.IsNull() {
49+
return fmt.Errorf("unmarshaling null values is not supported")
50+
}
51+
if !val.IsKnown() {
52+
return fmt.Errorf("unmarshaling unknown values is not supported")
53+
}
54+
switch target := dst.(type) {
55+
case *string:
56+
v, ok := val.value.(string)
57+
if !ok {
58+
return fmt.Errorf("can't unmarshal %s into %T, expected string", val.typ, dst)
59+
}
60+
*target = v
61+
case *big.Float:
62+
v, ok := val.value.(*big.Float)
63+
if !ok {
64+
return fmt.Errorf("can't unmarshal %s into %T, expected *big.Float", val.typ, dst)
65+
}
66+
target.Set(v)
67+
case *bool:
68+
v, ok := val.value.(bool)
69+
if !ok {
70+
return fmt.Errorf("can't unmarshal %s into %T, expected boolean", val.typ, dst)
71+
}
72+
*target = v
73+
case *map[string]Value:
74+
v, ok := val.value.(map[string]Value)
75+
if !ok {
76+
return fmt.Errorf("can't unmarshal %s into %T, expected map[string]tftypes.Value", val.typ, dst)
77+
}
78+
*target = v
79+
case *[]Value:
80+
v, ok := val.value.([]Value)
81+
if !ok {
82+
return fmt.Errorf("can't unmarshal %s into %T expected []tftypes.Value", val.typ, dst)
83+
}
84+
*target = v
85+
}
86+
return fmt.Errorf("can't unmarshal into %T, needs UnmarshalTerraform5Type method", dst)
4987
}
5088

5189
func (v Value) Is(t Type) bool {

0 commit comments

Comments
 (0)