Skip to content

Commit cb7d9ba

Browse files
committed
add conversion function for cty type to tftype type
1 parent 28202ca commit cb7d9ba

File tree

5 files changed

+179
-126
lines changed

5 files changed

+179
-126
lines changed

helper/convert/convert.go

Lines changed: 0 additions & 122 deletions
This file was deleted.

helper/convert/type.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package convert
2+
3+
import (
4+
"github.com/hashicorp/go-cty/cty"
5+
"github.com/hashicorp/terraform-plugin-go/tftypes"
6+
)
7+
8+
func ConvertToTfType(in cty.Type) tftypes.Type {
9+
switch {
10+
case in.IsPrimitiveType():
11+
if in == cty.String {
12+
return tftypes.String
13+
}
14+
if in == cty.Bool {
15+
return tftypes.Bool
16+
}
17+
if in == cty.Number {
18+
return tftypes.Number
19+
}
20+
case in.IsListType():
21+
elemType := ConvertToTfType(in.ElementType())
22+
return tftypes.List{ElementType: elemType}
23+
case in.IsSetType():
24+
elemType := ConvertToTfType(in.ElementType())
25+
return tftypes.Set{ElementType: elemType}
26+
case in.IsMapType():
27+
elemType := ConvertToTfType(in.ElementType())
28+
return tftypes.Map{ElementType: elemType}
29+
case in.IsObjectType():
30+
attrTypes := map[string]tftypes.Type{}
31+
32+
for k, v := range in.AttributeTypes() {
33+
attrTypes[k] = ConvertToTfType(v)
34+
}
35+
return tftypes.Object{AttributeTypes: attrTypes}
36+
case in.IsTupleType():
37+
// TODO
38+
}
39+
return nil
40+
}

helper/convert/value.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package convert
2+
3+
import (
4+
"github.com/hashicorp/go-cty/cty"
5+
"github.com/hashicorp/terraform-plugin-go/tftypes"
6+
)
7+
8+
func PrimitiveTfValue(in cty.Value) tftypes.Value {
9+
if in.IsNull() {
10+
return emptyTfValue(ToTfType(in.Type()))
11+
}
12+
13+
var val tftypes.Value
14+
switch in.Type() {
15+
case cty.String:
16+
val = tftypes.NewValue(tftypes.String, in.AsString())
17+
case cty.Bool:
18+
val = tftypes.NewValue(tftypes.Bool, in.True())
19+
case cty.Number:
20+
val = tftypes.NewValue(tftypes.Number, in.AsBigFloat())
21+
// TODO other number types?
22+
}
23+
24+
return val
25+
}
26+
27+
func ListTfValue(in cty.Value) tftypes.Value {
28+
listType := ToTfType(in.Type())
29+
30+
if in.IsNull() || in.LengthInt() == 0 {
31+
return emptyTfValue(listType)
32+
}
33+
34+
vals := make([]tftypes.Value, 0)
35+
36+
for _, v := range in.AsValueSlice() {
37+
vals = append(vals, ToTfValue(v))
38+
}
39+
40+
return tftypes.NewValue(listType, vals)
41+
}
42+
43+
func MapTfValue(in cty.Value) tftypes.Value {
44+
mapType := ToTfType(in.Type())
45+
46+
if in.IsNull() || in.LengthInt() == 0 {
47+
return emptyTfValue(mapType)
48+
}
49+
50+
vals := make(map[string]tftypes.Value)
51+
52+
for k, v := range in.AsValueMap() {
53+
vals[k] = ToTfValue(v)
54+
}
55+
56+
return tftypes.NewValue(mapType, vals)
57+
}
58+
59+
func SetTfValue(in cty.Value) tftypes.Value {
60+
setType := ToTfType(in.Type())
61+
62+
if in.IsNull() || in.LengthInt() == 0 {
63+
return emptyTfValue(setType)
64+
}
65+
66+
vals := make([]tftypes.Value, 0)
67+
68+
for _, v := range in.AsValueSlice() {
69+
vals = append(vals, ToTfValue(v))
70+
}
71+
72+
return tftypes.NewValue(setType, vals)
73+
}
74+
75+
func ObjectTfValue(in cty.Value) tftypes.Value {
76+
objType := ToTfType(in.Type())
77+
78+
if in.IsNull() || in.LengthInt() == 0 {
79+
return emptyTfValue(objType)
80+
}
81+
82+
vals := make(map[string]tftypes.Value)
83+
84+
for k, v := range in.AsValueMap() {
85+
vals[k] = ToTfValue(v)
86+
}
87+
88+
return tftypes.NewValue(objType, vals)
89+
}
90+
91+
func ToTfValue(in cty.Value) tftypes.Value {
92+
ty := in.Type()
93+
switch {
94+
case ty.IsPrimitiveType():
95+
return PrimitiveTfValue(in)
96+
case ty.IsListType():
97+
return ListTfValue(in)
98+
case ty.IsObjectType():
99+
return ObjectTfValue(in)
100+
case ty.IsMapType():
101+
return MapTfValue(in)
102+
case ty.IsSetType():
103+
return SetTfValue(in)
104+
case ty.IsTupleType():
105+
// TODO
106+
}
107+
108+
return emptyTfValue(ToTfType(in.Type()))
109+
}
110+
111+
func emptyTfValue(ty tftypes.Type) tftypes.Value {
112+
return tftypes.NewValue(ty, nil)
113+
}

helper/convert/convert_test.go renamed to helper/convert/value_test.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func TestPrimitiveTfType(t *testing.T) {
3434
t.Run(test.Value.GoString(), func(t *testing.T) {
3535
t.Parallel()
3636

37-
got := PrimitiveTfType(test.Value)
37+
got := PrimitiveTfValue(test.Value)
3838

3939
if diff := cmp.Diff(test.Want, got); diff != "" {
4040
t.Errorf("unexpected differences: %s", diff)
@@ -142,13 +142,35 @@ func TestListTfType(t *testing.T) {
142142
}),
143143
}),
144144
},
145+
{
146+
Value: cty.ListVal([]cty.Value{
147+
cty.ObjectVal(map[string]cty.Value{
148+
"enforcement": cty.NullVal(cty.String),
149+
}),
150+
}),
151+
Want: tftypes.NewValue(tftypes.List{
152+
ElementType: tftypes.Object{
153+
AttributeTypes: map[string]tftypes.Type{
154+
"enforcement": tftypes.String,
155+
},
156+
},
157+
}, []tftypes.Value{
158+
tftypes.NewValue(tftypes.Object{
159+
AttributeTypes: map[string]tftypes.Type{
160+
"enforcement": tftypes.String,
161+
},
162+
}, map[string]tftypes.Value{
163+
"enforcement": tftypes.NewValue(tftypes.String, nil),
164+
}),
165+
}),
166+
},
145167
}
146168

147169
for _, test := range tests {
148170
t.Run(test.Value.GoString(), func(t *testing.T) {
149171
t.Parallel()
150172

151-
got := ListTfType(test.Value)
173+
got := ListTfValue(test.Value)
152174

153175
if diff := cmp.Diff(test.Want, got); diff != "" {
154176
t.Errorf("unexpected differences: %s", diff)

helper/schema/resource_data.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func (d *ResourceData) TfTypeIdentity() tftypes.Value {
7373
// TODO should we return an error of panic if something goes wrong here
7474
}
7575

76-
return convert.ObjectTfType(stateVal)
76+
return convert.ToTfValue(stateVal)
7777
}
7878

7979
func (d *ResourceData) TfTypeResource() tftypes.Value {
@@ -145,7 +145,7 @@ func (d *ResourceData) TfTypeResource() tftypes.Value {
145145
// TODO should we return an error of panic if something goes wrong here
146146
}
147147

148-
return convert.ObjectTfType(stateVal)
148+
return convert.ToTfValue(stateVal)
149149
}
150150

151151
// Get returns the data for the given key, or nil if the key doesn't exist

0 commit comments

Comments
 (0)