Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

types: Remove Attrs, AttrTypes, Elems, ElemTypes, Null, Unknown, and Value fields #523

Merged
merged 3 commits into from Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 47 additions & 0 deletions .changelog/523.txt
@@ -0,0 +1,47 @@
```release-note:breaking-change
types: The `Bool` type `Null`, `Unknown`, and `Value` fields have been removed. Use the `BoolNull()`, `BoolUnknown()`, and `BoolValue()` creation functions and `IsNull()`, `IsUnknown()`, and `ValueBool()` methods instead.
```

```release-note:breaking-change
types: The `Float64` type `Null`, `Unknown`, and `Value` fields have been removed. Use the `Float64Null()`, `Float64Unknown()`, and `Float64Value()` creation functions and `IsNull()`, `IsUnknown()`, and `ValueFloat64()` methods instead.
```

```release-note:breaking-change
types: The `Int64` type `Null`, `Unknown`, and `Value` fields have been removed. Use the `Int64Null()`, `Int64Unknown()`, and `Int64Value()` creation functions and `IsNull()`, `IsUnknown()`, and `ValueInt64()` methods instead.
```

```release-note:breaking-change
types: The `List` type `Elems`, `ElemType`, `Null`, and `Unknown` fields have been removed. Use the `ListNull()`, `ListUnknown()`, `ListValue()`, and `ListValueMust()` creation functions and `Elements()`, `ElementsAs()`, `ElementType()`, `IsNull()`, and `IsUnknown()` methods instead.
```

```release-note:breaking-change
types: The `Map` type `Elems`, `ElemType`, `Null`, and `Unknown` fields have been removed. Use the `MapNull()`, `MapUnknown()`, `MapValue()`, and `MapValueMust()` creation functions and `Elements()`, `ElementsAs()`, `ElementType()`, `IsNull()`, and `IsUnknown()` methods instead.
```

```release-note:breaking-change
types: The `Number` type `Null`, `Unknown`, and `Value` fields have been removed. Use the `NumberNull()`, `NumberUnknown()`, and `NumberValue()` creation functions and `IsNull()`, `IsUnknown()`, and `ValueBigFloat()` methods instead.
```

```release-note:breaking-change
types: The `Object` type `Attrs`, `AttrTypes`, `Null`, and `Unknown` fields have been removed. Use the `ObjectNull()`, `ObjectUnknown()`, `ObjectValue()`, and `ObjectValueMust()` creation functions and `As()`, `Attributes()`, `AttributeTypes()`, `IsNull()`, and `IsUnknown()` methods instead.
```

```release-note:breaking-change
types: The `Set` type `Elems`, `ElemType`, `Null`, and `Unknown` fields have been removed. Use the `SetNull()`, `SetUnknown()`, `SetValue()`, and `SetValueMust()` creation functions and `Elements()`, `ElementsAs()`, `ElementType()`, `IsNull()`, and `IsUnknown()` methods instead.
```

```release-note:breaking-change
types: The `String` type `Null`, `Unknown`, and `Value` fields have been removed. Use the `StringNull()`, `StringUnknown()`, and `StringValue()` creation functions and `IsNull()`, `IsUnknown()`, and `ValueString()` methods instead.
```

```release-note:enhancement
attr: Added `ValueState` type, which custom types can use to consistently represent the three possible value states (known, null, and unknown)
```

```release-note:bug
types: Prevented Terraform errors where the zero-value for any `attr.Value` types such as `String` would be a known value instead of null
```

```release-note:bug
types: Prevented indeterminate behavior for any `attr.Value` types where they could be any combination of null, unknown, and/or known
```
31 changes: 31 additions & 0 deletions attr/value_state.go
@@ -0,0 +1,31 @@
package attr

import "fmt"

const (
// ValueStateNull represents a value which is null.
//
// This value is 0 so it is the zero-value for types implementations.
ValueStateNull ValueState = 0

// ValueStateUnknown represents a value which is unknown.
ValueStateUnknown ValueState = 1

// ValueStateKnown represents a value which is known (not null or unknown).
ValueStateKnown ValueState = 2
)

type ValueState uint8

func (s ValueState) String() string {
switch s {
case ValueStateKnown:
return "known"
case ValueStateNull:
return "null"
case ValueStateUnknown:
return "unknown"
default:
panic(fmt.Sprintf("unhandled ValueState in String: %d", s))
}
}
2 changes: 1 addition & 1 deletion internal/fromtftypes/attribute_path_step_test.go
Expand Up @@ -43,7 +43,7 @@ func TestAttributePathStep(t *testing.T) {
"PathStepElementKeyValue": {
tfType: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")),
attrType: types.StringType,
expected: path.PathStepElementKeyValue{Value: types.String{Value: "test"}},
expected: path.PathStepElementKeyValue{Value: types.StringValue("test")},
},
"PathStepElementKeyValue-error": {
tfType: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")),
Expand Down
2 changes: 1 addition & 1 deletion internal/fromtftypes/attribute_path_test.go
Expand Up @@ -88,7 +88,7 @@ func TestAttributePath(t *testing.T) {
},
},
},
expected: path.Root("test").AtSetValue(types.String{Value: "test-value"}),
expected: path.Root("test").AtSetValue(types.StringValue("test-value")),
},
"AttributeName-ElementKeyValue-value-conversion-error": {
tfType: tftypes.NewAttributePath().WithAttributeName("test").WithElementKeyValue(tftypes.NewValue(tftypes.String, "test-value")),
Expand Down
96 changes: 41 additions & 55 deletions internal/fromtftypes/value_test.go
Expand Up @@ -27,7 +27,7 @@ func TestValue(t *testing.T) {
"empty-tftype": {
tfType: tftypes.Value{},
attrType: types.BoolType,
expected: types.Bool{Null: true},
expected: types.BoolNull(),
},
"nil-attr-type": {
tfType: tftypes.Value{},
Expand All @@ -44,47 +44,47 @@ func TestValue(t *testing.T) {
"bool-null": {
tfType: tftypes.NewValue(tftypes.Bool, nil),
attrType: types.BoolType,
expected: types.Bool{Null: true},
expected: types.BoolNull(),
},
"bool-unknown": {
tfType: tftypes.NewValue(tftypes.Bool, tftypes.UnknownValue),
attrType: types.BoolType,
expected: types.Bool{Unknown: true},
expected: types.BoolUnknown(),
},
"bool-value": {
tfType: tftypes.NewValue(tftypes.Bool, true),
attrType: types.BoolType,
expected: types.Bool{Value: true},
expected: types.BoolValue(true),
},
"float64-null": {
tfType: tftypes.NewValue(tftypes.Number, nil),
attrType: types.Float64Type,
expected: types.Float64{Null: true},
expected: types.Float64Null(),
},
"float64-unknown": {
tfType: tftypes.NewValue(tftypes.Number, tftypes.UnknownValue),
attrType: types.Float64Type,
expected: types.Float64{Unknown: true},
expected: types.Float64Unknown(),
},
"float64-value": {
tfType: tftypes.NewValue(tftypes.Number, big.NewFloat(1.2)),
attrType: types.Float64Type,
expected: types.Float64{Value: 1.2},
expected: types.Float64Value(1.2),
},
"int64-null": {
tfType: tftypes.NewValue(tftypes.Number, nil),
attrType: types.Int64Type,
expected: types.Int64{Null: true},
expected: types.Int64Null(),
},
"int64-unknown": {
tfType: tftypes.NewValue(tftypes.Number, tftypes.UnknownValue),
attrType: types.Int64Type,
expected: types.Int64{Unknown: true},
expected: types.Int64Unknown(),
},
"int64-value": {
tfType: tftypes.NewValue(tftypes.Number, 123),
attrType: types.Int64Type,
expected: types.Int64{Value: 123},
expected: types.Int64Value(123),
},
"list-null": {
tfType: tftypes.NewValue(
Expand All @@ -96,10 +96,7 @@ func TestValue(t *testing.T) {
attrType: types.ListType{
ElemType: types.StringType,
},
expected: types.List{
ElemType: types.StringType,
Null: true,
},
expected: types.ListNull(types.StringType),
},
"list-unknown": {
tfType: tftypes.NewValue(
Expand All @@ -111,10 +108,7 @@ func TestValue(t *testing.T) {
attrType: types.ListType{
ElemType: types.StringType,
},
expected: types.List{
ElemType: types.StringType,
Unknown: true,
},
expected: types.ListUnknown(types.StringType),
},
"list-value": {
tfType: tftypes.NewValue(
Expand All @@ -128,27 +122,27 @@ func TestValue(t *testing.T) {
attrType: types.ListType{
ElemType: types.StringType,
},
expected: types.List{
ElemType: types.StringType,
Elems: []attr.Value{
types.String{Value: "test-value"},
expected: types.ListValueMust(
types.StringType,
[]attr.Value{
types.StringValue("test-value"),
},
},
),
},
"number-null": {
tfType: tftypes.NewValue(tftypes.Number, nil),
attrType: types.NumberType,
expected: types.Number{Null: true},
expected: types.NumberNull(),
},
"number-unknown": {
tfType: tftypes.NewValue(tftypes.Number, tftypes.UnknownValue),
attrType: types.NumberType,
expected: types.Number{Unknown: true},
expected: types.NumberUnknown(),
},
"number-value": {
tfType: tftypes.NewValue(tftypes.Number, big.NewFloat(1.2)),
attrType: types.NumberType,
expected: types.Number{Value: big.NewFloat(1.2)},
expected: types.NumberValue(big.NewFloat(1.2)),
},
"object-null": {
tfType: tftypes.NewValue(
Expand All @@ -164,12 +158,11 @@ func TestValue(t *testing.T) {
"test_attr": types.StringType,
},
},
expected: types.Object{
AttrTypes: map[string]attr.Type{
expected: types.ObjectNull(
map[string]attr.Type{
"test_attr": types.StringType,
},
Null: true,
},
),
},
"object-unknown": {
tfType: tftypes.NewValue(
Expand All @@ -185,12 +178,11 @@ func TestValue(t *testing.T) {
"test_attr": types.StringType,
},
},
expected: types.Object{
AttrTypes: map[string]attr.Type{
expected: types.ObjectUnknown(
map[string]attr.Type{
"test_attr": types.StringType,
},
Unknown: true,
},
),
},
"object-value": {
tfType: tftypes.NewValue(
Expand All @@ -208,14 +200,14 @@ func TestValue(t *testing.T) {
"test_attr": types.StringType,
},
},
expected: types.Object{
AttrTypes: map[string]attr.Type{
expected: types.ObjectValueMust(
map[string]attr.Type{
"test_attr": types.StringType,
},
Attrs: map[string]attr.Value{
"test_attr": types.String{Value: "test-value"},
map[string]attr.Value{
"test_attr": types.StringValue("test-value"),
},
},
),
},
"set-null": {
tfType: tftypes.NewValue(
Expand All @@ -227,10 +219,7 @@ func TestValue(t *testing.T) {
attrType: types.SetType{
ElemType: types.StringType,
},
expected: types.Set{
ElemType: types.StringType,
Null: true,
},
expected: types.SetNull(types.StringType),
},
"set-unknown": {
tfType: tftypes.NewValue(
Expand All @@ -242,10 +231,7 @@ func TestValue(t *testing.T) {
attrType: types.SetType{
ElemType: types.StringType,
},
expected: types.Set{
ElemType: types.StringType,
Unknown: true,
},
expected: types.SetUnknown(types.StringType),
},
"set-value": {
tfType: tftypes.NewValue(
Expand All @@ -259,27 +245,27 @@ func TestValue(t *testing.T) {
attrType: types.SetType{
ElemType: types.StringType,
},
expected: types.Set{
ElemType: types.StringType,
Elems: []attr.Value{
types.String{Value: "test-value"},
expected: types.SetValueMust(
types.StringType,
[]attr.Value{
types.StringValue("test-value"),
},
},
),
},
"string-null": {
tfType: tftypes.NewValue(tftypes.String, nil),
attrType: types.StringType,
expected: types.String{Null: true},
expected: types.StringNull(),
},
"string-unknown": {
tfType: tftypes.NewValue(tftypes.String, tftypes.UnknownValue),
attrType: types.StringType,
expected: types.String{Unknown: true},
expected: types.StringUnknown(),
},
"string-value": {
tfType: tftypes.NewValue(tftypes.String, "test-value"),
attrType: types.StringType,
expected: types.String{Value: "test-value"},
expected: types.StringValue("test-value"),
},
}

Expand Down