diff --git a/.changelog/567.txt b/.changelog/567.txt new file mode 100644 index 000000000..031522a08 --- /dev/null +++ b/.changelog/567.txt @@ -0,0 +1,11 @@ +```release-note:feature +types/basetypes: New package which contains embeddable types for custom types +``` + +```release-note:breaking-change +types: The type-specific `Typable` and `Valuable` interfaces have been moved into the underlying `basetypes` package. +``` + +```release-note:note +types: Framework type implementations have been moved into the underlying `basetypes` package. Value creation functions and type aliases have been created in the `types` package that should prevent any breaking changes. +``` diff --git a/datasource/schema/bool_attribute.go b/datasource/schema/bool_attribute.go index 4226c8a9e..4e9f5df9a 100644 --- a/datasource/schema/bool_attribute.go +++ b/datasource/schema/bool_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -29,9 +30,9 @@ var ( // .example_attribute type BoolAttribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.BoolType. When retrieving data, the types.BoolValuable + // default basetypes.BoolType. When retrieving data, the basetypes.BoolValuable // associated with this custom type must be used in place of types.Bool. - CustomType types.BoolTypable + CustomType basetypes.BoolTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/bool_attribute_test.go b/datasource/schema/bool_attribute_test.go index c26712b1e..558f4c21c 100644 --- a/datasource/schema/bool_attribute_test.go +++ b/datasource/schema/bool_attribute_test.go @@ -29,25 +29,25 @@ func TestBoolAttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.BoolAttribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.BoolType"), }, "ElementKeyInt": { attribute: schema.BoolAttribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.BoolType"), }, "ElementKeyString": { attribute: schema.BoolAttribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.BoolType"), }, "ElementKeyValue": { attribute: schema.BoolAttribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.BoolType"), }, } diff --git a/datasource/schema/float64_attribute.go b/datasource/schema/float64_attribute.go index 51d3ca6d9..cdb6e5c22 100644 --- a/datasource/schema/float64_attribute.go +++ b/datasource/schema/float64_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -32,9 +33,9 @@ var ( // .example_attribute type Float64Attribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.Float64Type. When retrieving data, the types.Float64Valuable + // default basetypes.Float64Type. When retrieving data, the basetypes.Float64Valuable // associated with this custom type must be used in place of types.Float64. - CustomType types.Float64Typable + CustomType basetypes.Float64Typable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/float64_attribute_test.go b/datasource/schema/float64_attribute_test.go index 0c0a3d29f..b49ee3ebf 100644 --- a/datasource/schema/float64_attribute_test.go +++ b/datasource/schema/float64_attribute_test.go @@ -28,25 +28,25 @@ func TestFloat64AttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.Float64Attribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.Float64Type"), }, "ElementKeyInt": { attribute: schema.Float64Attribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.Float64Type"), }, "ElementKeyString": { attribute: schema.Float64Attribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.Float64Type"), }, "ElementKeyValue": { attribute: schema.Float64Attribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.Float64Type"), }, } diff --git a/datasource/schema/int64_attribute.go b/datasource/schema/int64_attribute.go index 52ec92c24..b3efd6169 100644 --- a/datasource/schema/int64_attribute.go +++ b/datasource/schema/int64_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -32,9 +33,9 @@ var ( // .example_attribute type Int64Attribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.Int64Type. When retrieving data, the types.Int64Valuable + // default basetypes.Int64Type. When retrieving data, the basetypes.Int64Valuable // associated with this custom type must be used in place of types.Int64. - CustomType types.Int64Typable + CustomType basetypes.Int64Typable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/int64_attribute_test.go b/datasource/schema/int64_attribute_test.go index 640a94099..7b97d9579 100644 --- a/datasource/schema/int64_attribute_test.go +++ b/datasource/schema/int64_attribute_test.go @@ -28,25 +28,25 @@ func TestInt64AttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.Int64Attribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.Int64Type"), }, "ElementKeyInt": { attribute: schema.Int64Attribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.Int64Type"), }, "ElementKeyString": { attribute: schema.Int64Attribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.Int64Type"), }, "ElementKeyValue": { attribute: schema.Int64Attribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.Int64Type"), }, } diff --git a/datasource/schema/list_attribute.go b/datasource/schema/list_attribute.go index dbe3ac116..01a323c43 100644 --- a/datasource/schema/list_attribute.go +++ b/datasource/schema/list_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -40,9 +41,9 @@ type ListAttribute struct { ElementType attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.ListType. When retrieving data, the types.ListValuable + // default basetypes.ListType. When retrieving data, the basetypes.ListValuable // associated with this custom type must be used in place of types.List. - CustomType types.ListTypable + CustomType basetypes.ListTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/list_nested_attribute.go b/datasource/schema/list_nested_attribute.go index 081006956..a45379db2 100644 --- a/datasource/schema/list_nested_attribute.go +++ b/datasource/schema/list_nested_attribute.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -51,9 +52,9 @@ type ListNestedAttribute struct { // CustomType enables the use of a custom attribute type in place of the // default types.ListType of types.ObjectType. When retrieving data, the - // types.ListValuable associated with this custom type must be used in + // basetypes.ListValuable associated with this custom type must be used in // place of types.List. - CustomType types.ListTypable + CustomType basetypes.ListTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/list_nested_block.go b/datasource/schema/list_nested_block.go index 29cf34465..29fc172a0 100644 --- a/datasource/schema/list_nested_block.go +++ b/datasource/schema/list_nested_block.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -55,9 +56,9 @@ type ListNestedBlock struct { // CustomType enables the use of a custom attribute type in place of the // default types.ListType of types.ObjectType. When retrieving data, the - // types.ListValuable associated with this custom type must be used in + // basetypes.ListValuable associated with this custom type must be used in // place of types.List. - CustomType types.ListTypable + CustomType basetypes.ListTypable // Description is used in various tooling, like the language server, to // give practitioners more information about what this attribute is, diff --git a/datasource/schema/map_attribute.go b/datasource/schema/map_attribute.go index ab49d07ed..d1cd782d0 100644 --- a/datasource/schema/map_attribute.go +++ b/datasource/schema/map_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -43,9 +44,9 @@ type MapAttribute struct { ElementType attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.MapType. When retrieving data, the types.MapValuable + // default basetypes.MapType. When retrieving data, the basetypes.MapValuable // associated with this custom type must be used in place of types.Map. - CustomType types.MapTypable + CustomType basetypes.MapTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/map_nested_attribute.go b/datasource/schema/map_nested_attribute.go index d5f32321a..2ca7cd89b 100644 --- a/datasource/schema/map_nested_attribute.go +++ b/datasource/schema/map_nested_attribute.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) // Ensure the implementation satisifies the desired interfaces. @@ -52,9 +53,9 @@ type MapNestedAttribute struct { // CustomType enables the use of a custom attribute type in place of the // default types.MapType of types.ObjectType. When retrieving data, the - // types.MapValuable associated with this custom type must be used in + // basetypes.MapValuable associated with this custom type must be used in // place of types.Map. - CustomType types.MapTypable + CustomType basetypes.MapTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/nested_attribute_object.go b/datasource/schema/nested_attribute_object.go index a0b64e637..ae41a1873 100644 --- a/datasource/schema/nested_attribute_object.go +++ b/datasource/schema/nested_attribute_object.go @@ -4,7 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -27,9 +27,9 @@ type NestedAttributeObject struct { Attributes map[string]Attribute // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Validators define value validation functionality for the attribute. All // elements of the slice of AttributeValidator are run, regardless of any @@ -70,7 +70,7 @@ func (o NestedAttributeObject) ObjectValidators() []validator.Object { } // Type returns the framework type of the NestedAttributeObject. -func (o NestedAttributeObject) Type() types.ObjectTypable { +func (o NestedAttributeObject) Type() basetypes.ObjectTypable { if o.CustomType != nil { return o.CustomType } diff --git a/datasource/schema/nested_block_object.go b/datasource/schema/nested_block_object.go index 1885f3694..ea0cf61d6 100644 --- a/datasource/schema/nested_block_object.go +++ b/datasource/schema/nested_block_object.go @@ -4,7 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -34,9 +34,9 @@ type NestedBlockObject struct { Blocks map[string]Block // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Validators define value validation functionality for the attribute. All // elements of the slice of AttributeValidator are run, regardless of any @@ -82,7 +82,7 @@ func (o NestedBlockObject) ObjectValidators() []validator.Object { } // Type returns the framework type of the NestedBlockObject. -func (o NestedBlockObject) Type() types.ObjectTypable { +func (o NestedBlockObject) Type() basetypes.ObjectTypable { if o.CustomType != nil { return o.CustomType } diff --git a/datasource/schema/number_attribute.go b/datasource/schema/number_attribute.go index 2a30e692a..5e2b57fe7 100644 --- a/datasource/schema/number_attribute.go +++ b/datasource/schema/number_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -33,9 +34,9 @@ var ( // .example_attribute type NumberAttribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.NumberType. When retrieving data, the types.NumberValuable + // default basetypes.NumberType. When retrieving data, the basetypes.NumberValuable // associated with this custom type must be used in place of types.Number. - CustomType types.NumberTypable + CustomType basetypes.NumberTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/number_attribute_test.go b/datasource/schema/number_attribute_test.go index 260b74382..41fcf31ca 100644 --- a/datasource/schema/number_attribute_test.go +++ b/datasource/schema/number_attribute_test.go @@ -29,25 +29,25 @@ func TestNumberAttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.NumberAttribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.NumberType"), }, "ElementKeyInt": { attribute: schema.NumberAttribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.NumberType"), }, "ElementKeyString": { attribute: schema.NumberAttribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.NumberType"), }, "ElementKeyValue": { attribute: schema.NumberAttribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.NumberType"), }, } diff --git a/datasource/schema/object_attribute.go b/datasource/schema/object_attribute.go index 5ac4cb3f4..9d52f5d06 100644 --- a/datasource/schema/object_attribute.go +++ b/datasource/schema/object_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -42,9 +43,9 @@ type ObjectAttribute struct { AttributeTypes map[string]attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/set_attribute.go b/datasource/schema/set_attribute.go index f78aabd50..2eed08677 100644 --- a/datasource/schema/set_attribute.go +++ b/datasource/schema/set_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -38,9 +39,9 @@ type SetAttribute struct { ElementType attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.SetType. When retrieving data, the types.SetValuable + // default basetypes.SetType. When retrieving data, the basetypes.SetValuable // associated with this custom type must be used in place of types.Set. - CustomType types.SetTypable + CustomType basetypes.SetTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/set_nested_attribute.go b/datasource/schema/set_nested_attribute.go index 51f759489..40dc28051 100644 --- a/datasource/schema/set_nested_attribute.go +++ b/datasource/schema/set_nested_attribute.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) // Ensure the implementation satisifies the desired interfaces. @@ -47,9 +48,9 @@ type SetNestedAttribute struct { // CustomType enables the use of a custom attribute type in place of the // default types.SetType of types.ObjectType. When retrieving data, the - // types.SetValuable associated with this custom type must be used in + // basetypes.SetValuable associated with this custom type must be used in // place of types.Set. - CustomType types.SetTypable + CustomType basetypes.SetTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/set_nested_block.go b/datasource/schema/set_nested_block.go index a21310abe..87d453f66 100644 --- a/datasource/schema/set_nested_block.go +++ b/datasource/schema/set_nested_block.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -55,9 +56,9 @@ type SetNestedBlock struct { // CustomType enables the use of a custom attribute type in place of the // default types.SetType of types.ObjectType. When retrieving data, the - // types.SetValuable associated with this custom type must be used in + // basetypes.SetValuable associated with this custom type must be used in // place of types.Set. - CustomType types.SetTypable + CustomType basetypes.SetTypable // Description is used in various tooling, like the language server, to // give practitioners more information about what this attribute is, diff --git a/datasource/schema/single_nested_attribute.go b/datasource/schema/single_nested_attribute.go index 067b5f53d..77726bb63 100644 --- a/datasource/schema/single_nested_attribute.go +++ b/datasource/schema/single_nested_attribute.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) // Ensure the implementation satisifies the desired interfaces. @@ -46,9 +47,9 @@ type SingleNestedAttribute struct { Attributes map[string]Attribute // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/single_nested_block.go b/datasource/schema/single_nested_block.go index 63a2b72ce..3f082be2e 100644 --- a/datasource/schema/single_nested_block.go +++ b/datasource/schema/single_nested_block.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -56,9 +57,9 @@ type SingleNestedBlock struct { Blocks map[string]Block // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Description is used in various tooling, like the language server, to // give practitioners more information about what this attribute is, diff --git a/datasource/schema/string_attribute.go b/datasource/schema/string_attribute.go index 15c3431ed..ee6ee3830 100644 --- a/datasource/schema/string_attribute.go +++ b/datasource/schema/string_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -29,9 +30,9 @@ var ( // .example_attribute type StringAttribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.StringType. When retrieving data, the types.StringValuable + // default basetypes.StringType. When retrieving data, the basetypes.StringValuable // associated with this custom type must be used in place of types.String. - CustomType types.StringTypable + CustomType basetypes.StringTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/datasource/schema/string_attribute_test.go b/datasource/schema/string_attribute_test.go index 69c983a6a..ef6964373 100644 --- a/datasource/schema/string_attribute_test.go +++ b/datasource/schema/string_attribute_test.go @@ -29,25 +29,25 @@ func TestStringAttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.StringAttribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.StringType"), }, "ElementKeyInt": { attribute: schema.StringAttribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.StringType"), }, "ElementKeyString": { attribute: schema.StringAttribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.StringType"), }, "ElementKeyValue": { attribute: schema.StringAttribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.StringType"), }, } diff --git a/internal/fwschema/nested_attribute_object.go b/internal/fwschema/nested_attribute_object.go index 573b74c18..cc6f5bae7 100644 --- a/internal/fwschema/nested_attribute_object.go +++ b/internal/fwschema/nested_attribute_object.go @@ -5,6 +5,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -21,7 +22,7 @@ type NestedAttributeObject interface { GetAttributes() UnderlyingAttributes // Type should return the framework type of the object. - Type() types.ObjectTypable + Type() basetypes.ObjectTypable } // NestedAttributeObjectApplyTerraform5AttributePathStep is a helper function @@ -76,7 +77,7 @@ func NestedAttributeObjectEqual(a, b NestedAttributeObject) bool { // using the GetAttributes and GetBlocks methods. NestedAttributeObject // implementations should still include custom type functionality in addition // to using this helper. -func NestedAttributeObjectType(o NestedAttributeObject) types.ObjectTypable { +func NestedAttributeObjectType(o NestedAttributeObject) basetypes.ObjectTypable { attrTypes := make(map[string]attr.Type, len(o.GetAttributes())) for name, attribute := range o.GetAttributes() { diff --git a/internal/fwschema/nested_block_object.go b/internal/fwschema/nested_block_object.go index b3b8fdb8d..8e2bc17e3 100644 --- a/internal/fwschema/nested_block_object.go +++ b/internal/fwschema/nested_block_object.go @@ -5,6 +5,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -24,7 +25,7 @@ type NestedBlockObject interface { GetBlocks() map[string]Block // Type should return the framework type of the object. - Type() types.ObjectTypable + Type() basetypes.ObjectTypable } // NestedBlockObjectApplyTerraform5AttributePathStep is a helper function to @@ -101,7 +102,7 @@ func NestedBlockObjectEqual(a, b NestedBlockObject) bool { // using the GetAttributes and GetBlocks methods. NestedBlockObject // implementations should still include custom type functionality in addition // to using this helper. -func NestedBlockObjectType(o NestedBlockObject) types.ObjectTypable { +func NestedBlockObjectType(o NestedBlockObject) basetypes.ObjectTypable { attrTypes := make(map[string]attr.Type, len(o.GetAttributes())+len(o.GetBlocks())) for name, attribute := range o.GetAttributes() { diff --git a/internal/fwschema/underlying_attributes.go b/internal/fwschema/underlying_attributes.go index c1efdf560..1210b47bf 100644 --- a/internal/fwschema/underlying_attributes.go +++ b/internal/fwschema/underlying_attributes.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -54,14 +54,14 @@ func (u UnderlyingAttributes) Equal(o UnderlyingAttributes) bool { } // Type returns the framework type of the underlying attributes. -func (u UnderlyingAttributes) Type() types.ObjectTypable { +func (u UnderlyingAttributes) Type() basetypes.ObjectTypable { attrTypes := make(map[string]attr.Type, len(u)) for name, attr := range u { attrTypes[name] = attr.GetType() } - return types.ObjectType{ + return basetypes.ObjectType{ AttrTypes: attrTypes, } } diff --git a/internal/fwschemadata/data_get_at_path_test.go b/internal/fwschemadata/data_get_at_path_test.go index 8a12ee9b2..b81f1a6bb 100644 --- a/internal/fwschemadata/data_get_at_path_test.go +++ b/internal/fwschemadata/data_get_at_path_test.go @@ -292,7 +292,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: bool\nTarget Type: *bool\nSuggested Type: types.Bool", + "Path: bool\nTarget Type: *bool\nSuggested Type: basetypes.BoolValue", ), }, }, @@ -351,7 +351,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: bool\nTarget Type: bool\nSuggested `types` Type: types.Bool\nSuggested Pointer Type: *bool", + "Path: bool\nTarget Type: bool\nSuggested `types` Type: basetypes.BoolValue\nSuggested Pointer Type: *bool", ), }, }, @@ -385,7 +385,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: bool\nTarget Type: bool\nSuggested Type: types.Bool", + "Path: bool\nTarget Type: bool\nSuggested Type: basetypes.BoolValue", ), }, }, @@ -544,7 +544,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: float64\nTarget Type: *float64\nSuggested Type: types.Float64", + "Path: float64\nTarget Type: *float64\nSuggested Type: basetypes.Float64Value", ), }, }, @@ -603,7 +603,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: float64\nTarget Type: float64\nSuggested `types` Type: types.Float64\nSuggested Pointer Type: *float64", + "Path: float64\nTarget Type: float64\nSuggested `types` Type: basetypes.Float64Value\nSuggested Pointer Type: *float64", ), }, }, @@ -637,7 +637,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: float64\nTarget Type: float64\nSuggested Type: types.Float64", + "Path: float64\nTarget Type: float64\nSuggested Type: basetypes.Float64Value", ), }, }, @@ -796,7 +796,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: int64\nTarget Type: *int64\nSuggested Type: types.Int64", + "Path: int64\nTarget Type: *int64\nSuggested Type: basetypes.Int64Value", ), }, }, @@ -855,7 +855,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: int64\nTarget Type: int64\nSuggested `types` Type: types.Int64\nSuggested Pointer Type: *int64", + "Path: int64\nTarget Type: int64\nSuggested `types` Type: basetypes.Int64Value\nSuggested Pointer Type: *int64", ), }, }, @@ -889,7 +889,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: int64\nTarget Type: int64\nSuggested Type: types.Int64", + "Path: int64\nTarget Type: int64\nSuggested Type: basetypes.Int64Value", ), }, }, @@ -1205,7 +1205,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: list\nTarget Type: []types.Object\nSuggested Type: types.List", + "Path: list\nTarget Type: []basetypes.ObjectValue\nSuggested Type: basetypes.ListValue", ), }, }, @@ -1395,7 +1395,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: list\nTarget Type: []struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.List", + "Path: list\nTarget Type: []struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ListValue", ), }, }, @@ -1759,7 +1759,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: list\nTarget Type: []types.Object\nSuggested Type: types.List", + "Path: list\nTarget Type: []basetypes.ObjectValue\nSuggested Type: basetypes.ListValue", ), }, }, @@ -1949,7 +1949,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: list\nTarget Type: []struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.List", + "Path: list\nTarget Type: []struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ListValue", ), }, }, @@ -2210,7 +2210,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: list\nTarget Type: []types.String\nSuggested Type: types.List", + "Path: list\nTarget Type: []basetypes.StringValue\nSuggested Type: basetypes.ListValue", ), }, }, @@ -2327,7 +2327,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: list\nTarget Type: []string\nSuggested Type: types.List", + "Path: list\nTarget Type: []string\nSuggested Type: basetypes.ListValue", ), }, }, @@ -2658,7 +2658,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: map\nTarget Type: map[string]types.Object\nSuggested Type: types.Map", + "Path: map\nTarget Type: map[string]basetypes.ObjectValue\nSuggested Type: basetypes.MapValue", ), }, }, @@ -2848,7 +2848,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: map\nTarget Type: map[string]struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Map", + "Path: map\nTarget Type: map[string]struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.MapValue", ), }, }, @@ -3109,7 +3109,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: map\nTarget Type: map[string]types.String\nSuggested Type: types.Map", + "Path: map\nTarget Type: map[string]basetypes.StringValue\nSuggested Type: basetypes.MapValue", ), }, }, @@ -3226,7 +3226,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: map\nTarget Type: map[string]string\nSuggested Type: types.Map", + "Path: map\nTarget Type: map[string]string\nSuggested Type: basetypes.MapValue", ), }, }, @@ -3500,7 +3500,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: object\nTarget Type: *struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Object", + "Path: object\nTarget Type: *struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ObjectValue", ), }, }, @@ -3603,7 +3603,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: object\nTarget Type: struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested `types` Type: types.Object\nSuggested Pointer Type: *struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }", + "Path: object\nTarget Type: struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested `types` Type: basetypes.ObjectValue\nSuggested Pointer Type: *struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }", ), }, }, @@ -3658,7 +3658,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: object\nTarget Type: struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Object", + "Path: object\nTarget Type: struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ObjectValue", ), }, }, @@ -3997,7 +3997,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: set\nTarget Type: []types.Object\nSuggested Type: types.Set", + "Path: set\nTarget Type: []basetypes.ObjectValue\nSuggested Type: basetypes.SetValue", ), }, }, @@ -4187,7 +4187,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: set\nTarget Type: []struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Set", + "Path: set\nTarget Type: []struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.SetValue", ), }, }, @@ -4551,7 +4551,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: set\nTarget Type: []types.Object\nSuggested Type: types.Set", + "Path: set\nTarget Type: []basetypes.ObjectValue\nSuggested Type: basetypes.SetValue", ), }, }, @@ -4741,7 +4741,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: set\nTarget Type: []struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Set", + "Path: set\nTarget Type: []struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.SetValue", ), }, }, @@ -5002,7 +5002,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: set\nTarget Type: []types.String\nSuggested Type: types.Set", + "Path: set\nTarget Type: []basetypes.StringValue\nSuggested Type: basetypes.SetValue", ), }, }, @@ -5119,7 +5119,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: set\nTarget Type: []string\nSuggested Type: types.Set", + "Path: set\nTarget Type: []string\nSuggested Type: basetypes.SetValue", ), }, }, @@ -5398,7 +5398,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: object\nTarget Type: *struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Object", + "Path: object\nTarget Type: *struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ObjectValue", ), }, }, @@ -5503,7 +5503,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: object\nTarget Type: struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested `types` Type: types.Object\nSuggested Pointer Type: *struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }", + "Path: object\nTarget Type: struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested `types` Type: basetypes.ObjectValue\nSuggested Pointer Type: *struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }", ), }, }, @@ -5559,7 +5559,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: object\nTarget Type: struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Object", + "Path: object\nTarget Type: struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ObjectValue", ), }, }, @@ -5847,7 +5847,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: object\nTarget Type: *struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Object", + "Path: object\nTarget Type: *struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ObjectValue", ), }, }, @@ -5952,7 +5952,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: object\nTarget Type: struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested `types` Type: types.Object\nSuggested Pointer Type: *struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }", + "Path: object\nTarget Type: struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested `types` Type: basetypes.ObjectValue\nSuggested Pointer Type: *struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }", ), }, }, @@ -6008,7 +6008,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: object\nTarget Type: struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Object", + "Path: object\nTarget Type: struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ObjectValue", ), }, }, @@ -6191,7 +6191,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: string\nTarget Type: *string\nSuggested Type: types.String", + "Path: string\nTarget Type: *string\nSuggested Type: basetypes.StringValue", ), }, }, @@ -6250,7 +6250,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: string\nTarget Type: string\nSuggested `types` Type: types.String\nSuggested Pointer Type: *string", + "Path: string\nTarget Type: string\nSuggested `types` Type: basetypes.StringValue\nSuggested Pointer Type: *string", ), }, }, @@ -6284,7 +6284,7 @@ func TestDataGetAtPath(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: string\nTarget Type: string\nSuggested Type: types.String", + "Path: string\nTarget Type: string\nSuggested Type: basetypes.StringValue", ), }, }, diff --git a/internal/fwschemadata/data_get_test.go b/internal/fwschemadata/data_get_test.go index 8257c6cde..a8279a274 100644 --- a/internal/fwschemadata/data_get_test.go +++ b/internal/fwschemadata/data_get_test.go @@ -381,7 +381,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: bool\nTarget Type: *bool\nSuggested Type: types.Bool", + "Path: bool\nTarget Type: *bool\nSuggested Type: basetypes.BoolValue", ), }, }, @@ -450,7 +450,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: bool\nTarget Type: bool\nSuggested `types` Type: types.Bool\nSuggested Pointer Type: *bool", + "Path: bool\nTarget Type: bool\nSuggested `types` Type: basetypes.BoolValue\nSuggested Pointer Type: *bool", ), }, }, @@ -489,7 +489,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: bool\nTarget Type: bool\nSuggested Type: types.Bool", + "Path: bool\nTarget Type: bool\nSuggested Type: basetypes.BoolValue", ), }, }, @@ -678,7 +678,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: float64\nTarget Type: *float64\nSuggested Type: types.Float64", + "Path: float64\nTarget Type: *float64\nSuggested Type: basetypes.Float64Value", ), }, }, @@ -747,7 +747,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: float64\nTarget Type: float64\nSuggested `types` Type: types.Float64\nSuggested Pointer Type: *float64", + "Path: float64\nTarget Type: float64\nSuggested `types` Type: basetypes.Float64Value\nSuggested Pointer Type: *float64", ), }, }, @@ -786,7 +786,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: float64\nTarget Type: float64\nSuggested Type: types.Float64", + "Path: float64\nTarget Type: float64\nSuggested Type: basetypes.Float64Value", ), }, }, @@ -975,7 +975,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: int64\nTarget Type: *int64\nSuggested Type: types.Int64", + "Path: int64\nTarget Type: *int64\nSuggested Type: basetypes.Int64Value", ), }, }, @@ -1044,7 +1044,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: int64\nTarget Type: int64\nSuggested `types` Type: types.Int64\nSuggested Pointer Type: *int64", + "Path: int64\nTarget Type: int64\nSuggested `types` Type: basetypes.Int64Value\nSuggested Pointer Type: *int64", ), }, }, @@ -1083,7 +1083,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: int64\nTarget Type: int64\nSuggested Type: types.Int64", + "Path: int64\nTarget Type: int64\nSuggested Type: basetypes.Int64Value", ), }, }, @@ -1429,7 +1429,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: list\nTarget Type: []types.Object\nSuggested Type: types.List", + "Path: list\nTarget Type: []basetypes.ObjectValue\nSuggested Type: basetypes.ListValue", ), }, }, @@ -1634,7 +1634,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: list\nTarget Type: []struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.List", + "Path: list\nTarget Type: []struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ListValue", ), }, }, @@ -2030,7 +2030,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: list\nTarget Type: []types.Object\nSuggested Type: types.List", + "Path: list\nTarget Type: []basetypes.ObjectValue\nSuggested Type: basetypes.ListValue", ), }, }, @@ -2235,7 +2235,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: list\nTarget Type: []struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.List", + "Path: list\nTarget Type: []struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ListValue", ), }, }, @@ -2528,7 +2528,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: list\nTarget Type: []types.String\nSuggested Type: types.List", + "Path: list\nTarget Type: []basetypes.StringValue\nSuggested Type: basetypes.ListValue", ), }, }, @@ -2660,7 +2660,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: list\nTarget Type: []string\nSuggested Type: types.List", + "Path: list\nTarget Type: []string\nSuggested Type: basetypes.ListValue", ), }, }, @@ -3021,7 +3021,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: map\nTarget Type: map[string]types.Object\nSuggested Type: types.Map", + "Path: map\nTarget Type: map[string]basetypes.ObjectValue\nSuggested Type: basetypes.MapValue", ), }, }, @@ -3226,7 +3226,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: map\nTarget Type: map[string]struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Map", + "Path: map\nTarget Type: map[string]struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.MapValue", ), }, }, @@ -3519,7 +3519,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: map\nTarget Type: map[string]types.String\nSuggested Type: types.Map", + "Path: map\nTarget Type: map[string]basetypes.StringValue\nSuggested Type: basetypes.MapValue", ), }, }, @@ -3651,7 +3651,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: map\nTarget Type: map[string]string\nSuggested Type: types.Map", + "Path: map\nTarget Type: map[string]string\nSuggested Type: basetypes.MapValue", ), }, }, @@ -3955,7 +3955,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: object\nTarget Type: *struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Object", + "Path: object\nTarget Type: *struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ObjectValue", ), }, }, @@ -4072,7 +4072,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: object\nTarget Type: struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested `types` Type: types.Object\nSuggested Pointer Type: *struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }", + "Path: object\nTarget Type: struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested `types` Type: basetypes.ObjectValue\nSuggested Pointer Type: *struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }", ), }, }, @@ -4134,7 +4134,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: object\nTarget Type: struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Object", + "Path: object\nTarget Type: struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ObjectValue", ), }, }, @@ -4505,7 +4505,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: set\nTarget Type: []types.Object\nSuggested Type: types.Set", + "Path: set\nTarget Type: []basetypes.ObjectValue\nSuggested Type: basetypes.SetValue", ), }, }, @@ -4710,7 +4710,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: set\nTarget Type: []struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Set", + "Path: set\nTarget Type: []struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.SetValue", ), }, }, @@ -5106,7 +5106,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: set\nTarget Type: []types.Object\nSuggested Type: types.Set", + "Path: set\nTarget Type: []basetypes.ObjectValue\nSuggested Type: basetypes.SetValue", ), }, }, @@ -5311,7 +5311,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: set\nTarget Type: []struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Set", + "Path: set\nTarget Type: []struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.SetValue", ), }, }, @@ -5604,7 +5604,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: set\nTarget Type: []types.String\nSuggested Type: types.Set", + "Path: set\nTarget Type: []basetypes.StringValue\nSuggested Type: basetypes.SetValue", ), }, }, @@ -5736,7 +5736,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: set\nTarget Type: []string\nSuggested Type: types.Set", + "Path: set\nTarget Type: []string\nSuggested Type: basetypes.SetValue", ), }, }, @@ -6045,7 +6045,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: object\nTarget Type: *struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Object", + "Path: object\nTarget Type: *struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ObjectValue", ), }, }, @@ -6164,7 +6164,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: object\nTarget Type: struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested `types` Type: types.Object\nSuggested Pointer Type: *struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }", + "Path: object\nTarget Type: struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested `types` Type: basetypes.ObjectValue\nSuggested Pointer Type: *struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }", ), }, }, @@ -6227,7 +6227,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: object\nTarget Type: struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Object", + "Path: object\nTarget Type: struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ObjectValue", ), }, }, @@ -6547,7 +6547,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: object\nTarget Type: *struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Object", + "Path: object\nTarget Type: *struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ObjectValue", ), }, }, @@ -6666,7 +6666,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: object\nTarget Type: struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested `types` Type: types.Object\nSuggested Pointer Type: *struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }", + "Path: object\nTarget Type: struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested `types` Type: basetypes.ObjectValue\nSuggested Pointer Type: *struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }", ), }, }, @@ -6729,7 +6729,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: object\nTarget Type: struct { NestedString types.String \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: types.Object", + "Path: object\nTarget Type: struct { NestedString basetypes.StringValue \"tfsdk:\\\"nested_string\\\"\" }\nSuggested Type: basetypes.ObjectValue", ), }, }, @@ -6944,7 +6944,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: string\nTarget Type: *string\nSuggested Type: types.String", + "Path: string\nTarget Type: *string\nSuggested Type: basetypes.StringValue", ), }, }, @@ -7013,7 +7013,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: string\nTarget Type: string\nSuggested `types` Type: types.String\nSuggested Pointer Type: *string", + "Path: string\nTarget Type: string\nSuggested `types` Type: basetypes.StringValue\nSuggested Pointer Type: *string", ), }, }, @@ -7052,7 +7052,7 @@ func TestDataGet(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: string\nTarget Type: string\nSuggested Type: types.String", + "Path: string\nTarget Type: string\nSuggested Type: basetypes.StringValue", ), }, }, diff --git a/internal/fwserver/attr_value.go b/internal/fwserver/attr_value.go index a2e855236..36072f1f0 100644 --- a/internal/fwserver/attr_value.go +++ b/internal/fwserver/attr_value.go @@ -10,10 +10,11 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschemadata" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) func coerceListValue(ctx context.Context, schemaPath path.Path, value attr.Value) (types.List, diag.Diagnostics) { - listVal, ok := value.(types.ListValuable) + listVal, ok := value.(basetypes.ListValuable) if !ok { return types.ListNull(nil), diag.Diagnostics{ @@ -25,7 +26,7 @@ func coerceListValue(ctx context.Context, schemaPath path.Path, value attr.Value } func coerceMapValue(ctx context.Context, schemaPath path.Path, value attr.Value) (types.Map, diag.Diagnostics) { - mapVal, ok := value.(types.MapValuable) + mapVal, ok := value.(basetypes.MapValuable) if !ok { return types.MapNull(nil), diag.Diagnostics{ @@ -37,7 +38,7 @@ func coerceMapValue(ctx context.Context, schemaPath path.Path, value attr.Value) } func coerceObjectValue(ctx context.Context, schemaPath path.Path, value attr.Value) (types.Object, diag.Diagnostics) { - objectVal, ok := value.(types.ObjectValuable) + objectVal, ok := value.(basetypes.ObjectValuable) if !ok { return types.ObjectNull(nil), diag.Diagnostics{ @@ -49,7 +50,7 @@ func coerceObjectValue(ctx context.Context, schemaPath path.Path, value attr.Val } func coerceSetValue(ctx context.Context, schemaPath path.Path, value attr.Value) (types.Set, diag.Diagnostics) { - setVal, ok := value.(types.SetValuable) + setVal, ok := value.(basetypes.SetValuable) if !ok { return types.SetNull(nil), diag.Diagnostics{ diff --git a/internal/fwserver/attribute_plan_modification.go b/internal/fwserver/attribute_plan_modification.go index 21a70a76d..04469c7eb 100644 --- a/internal/fwserver/attribute_plan_modification.go +++ b/internal/fwserver/attribute_plan_modification.go @@ -15,6 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) type ModifyAttributePlanResponse struct { @@ -443,18 +444,18 @@ func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.Mo // AttributePlanModifyBool performs all types.Bool plan modification. func AttributePlanModifyBool(ctx context.Context, attribute fwxschema.AttributeWithBoolPlanModifiers, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { - // Use types.BoolValuable until custom types cannot re-implement + // Use basetypes.BoolValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.BoolValuable) + configValuable, ok := req.AttributeConfig.(basetypes.BoolValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Bool Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Bool attribute plan modification. "+ - "The value type must implement the types.BoolValuable interface. "+ + "The value type must implement the basetypes.BoolValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -472,14 +473,14 @@ func AttributePlanModifyBool(ctx context.Context, attribute fwxschema.AttributeW return } - planValuable, ok := req.AttributePlan.(types.BoolValuable) + planValuable, ok := req.AttributePlan.(basetypes.BoolValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Bool Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Bool attribute plan modification. "+ - "The value type must implement the types.BoolValuable interface. "+ + "The value type must implement the basetypes.BoolValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), ) @@ -497,14 +498,14 @@ func AttributePlanModifyBool(ctx context.Context, attribute fwxschema.AttributeW return } - stateValuable, ok := req.AttributeState.(types.BoolValuable) + stateValuable, ok := req.AttributeState.(basetypes.BoolValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Bool Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Bool attribute plan modification. "+ - "The value type must implement the types.BoolValuable interface. "+ + "The value type must implement the basetypes.BoolValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), ) @@ -578,18 +579,18 @@ func AttributePlanModifyBool(ctx context.Context, attribute fwxschema.AttributeW // AttributePlanModifyFloat64 performs all types.Float64 plan modification. func AttributePlanModifyFloat64(ctx context.Context, attribute fwxschema.AttributeWithFloat64PlanModifiers, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { - // Use types.Float64Valuable until custom types cannot re-implement + // Use basetypes.Float64Valuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.Float64Valuable) + configValuable, ok := req.AttributeConfig.(basetypes.Float64Valuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Float64 Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Float64 attribute plan modification. "+ - "The value type must implement the types.Float64Valuable interface. "+ + "The value type must implement the basetypes.Float64Valuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -607,14 +608,14 @@ func AttributePlanModifyFloat64(ctx context.Context, attribute fwxschema.Attribu return } - planValuable, ok := req.AttributePlan.(types.Float64Valuable) + planValuable, ok := req.AttributePlan.(basetypes.Float64Valuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Float64 Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Float64 attribute plan modification. "+ - "The value type must implement the types.Float64Valuable interface. "+ + "The value type must implement the basetypes.Float64Valuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), ) @@ -632,14 +633,14 @@ func AttributePlanModifyFloat64(ctx context.Context, attribute fwxschema.Attribu return } - stateValuable, ok := req.AttributeState.(types.Float64Valuable) + stateValuable, ok := req.AttributeState.(basetypes.Float64Valuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Float64 Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Float64 attribute plan modification. "+ - "The value type must implement the types.Float64Valuable interface. "+ + "The value type must implement the basetypes.Float64Valuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), ) @@ -713,18 +714,18 @@ func AttributePlanModifyFloat64(ctx context.Context, attribute fwxschema.Attribu // AttributePlanModifyInt64 performs all types.Int64 plan modification. func AttributePlanModifyInt64(ctx context.Context, attribute fwxschema.AttributeWithInt64PlanModifiers, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { - // Use types.Int64Valuable until custom types cannot re-implement + // Use basetypes.Int64Valuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.Int64Valuable) + configValuable, ok := req.AttributeConfig.(basetypes.Int64Valuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Int64 Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Int64 attribute plan modification. "+ - "The value type must implement the types.Int64Valuable interface. "+ + "The value type must implement the basetypes.Int64Valuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -742,14 +743,14 @@ func AttributePlanModifyInt64(ctx context.Context, attribute fwxschema.Attribute return } - planValuable, ok := req.AttributePlan.(types.Int64Valuable) + planValuable, ok := req.AttributePlan.(basetypes.Int64Valuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Int64 Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Int64 attribute plan modification. "+ - "The value type must implement the types.Int64Valuable interface. "+ + "The value type must implement the basetypes.Int64Valuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), ) @@ -767,14 +768,14 @@ func AttributePlanModifyInt64(ctx context.Context, attribute fwxschema.Attribute return } - stateValuable, ok := req.AttributeState.(types.Int64Valuable) + stateValuable, ok := req.AttributeState.(basetypes.Int64Valuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Int64 Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Int64 attribute plan modification. "+ - "The value type must implement the types.Int64Valuable interface. "+ + "The value type must implement the basetypes.Int64Valuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), ) @@ -848,18 +849,18 @@ func AttributePlanModifyInt64(ctx context.Context, attribute fwxschema.Attribute // AttributePlanModifyList performs all types.List plan modification. func AttributePlanModifyList(ctx context.Context, attribute fwxschema.AttributeWithListPlanModifiers, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { - // Use types.ListValuable until custom types cannot re-implement + // Use basetypes.ListValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.ListValuable) + configValuable, ok := req.AttributeConfig.(basetypes.ListValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid List Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform List attribute plan modification. "+ - "The value type must implement the types.ListValuable interface. "+ + "The value type must implement the basetypes.ListValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -877,14 +878,14 @@ func AttributePlanModifyList(ctx context.Context, attribute fwxschema.AttributeW return } - planValuable, ok := req.AttributePlan.(types.ListValuable) + planValuable, ok := req.AttributePlan.(basetypes.ListValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid List Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform List attribute plan modification. "+ - "The value type must implement the types.ListValuable interface. "+ + "The value type must implement the basetypes.ListValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), ) @@ -902,14 +903,14 @@ func AttributePlanModifyList(ctx context.Context, attribute fwxschema.AttributeW return } - stateValuable, ok := req.AttributeState.(types.ListValuable) + stateValuable, ok := req.AttributeState.(basetypes.ListValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid List Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform List attribute plan modification. "+ - "The value type must implement the types.ListValuable interface. "+ + "The value type must implement the basetypes.ListValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), ) @@ -983,18 +984,18 @@ func AttributePlanModifyList(ctx context.Context, attribute fwxschema.AttributeW // AttributePlanModifyMap performs all types.Map plan modification. func AttributePlanModifyMap(ctx context.Context, attribute fwxschema.AttributeWithMapPlanModifiers, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { - // Use types.MapValuable until custom types cannot re-implement + // Use basetypes.MapValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.MapValuable) + configValuable, ok := req.AttributeConfig.(basetypes.MapValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Map Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Map attribute plan modification. "+ - "The value type must implement the types.MapValuable interface. "+ + "The value type must implement the basetypes.MapValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -1012,14 +1013,14 @@ func AttributePlanModifyMap(ctx context.Context, attribute fwxschema.AttributeWi return } - planValuable, ok := req.AttributePlan.(types.MapValuable) + planValuable, ok := req.AttributePlan.(basetypes.MapValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Map Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Map attribute plan modification. "+ - "The value type must implement the types.MapValuable interface. "+ + "The value type must implement the basetypes.MapValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), ) @@ -1037,14 +1038,14 @@ func AttributePlanModifyMap(ctx context.Context, attribute fwxschema.AttributeWi return } - stateValuable, ok := req.AttributeState.(types.MapValuable) + stateValuable, ok := req.AttributeState.(basetypes.MapValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Map Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Map attribute plan modification. "+ - "The value type must implement the types.MapValuable interface. "+ + "The value type must implement the basetypes.MapValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), ) @@ -1118,18 +1119,18 @@ func AttributePlanModifyMap(ctx context.Context, attribute fwxschema.AttributeWi // AttributePlanModifyNumber performs all types.Number plan modification. func AttributePlanModifyNumber(ctx context.Context, attribute fwxschema.AttributeWithNumberPlanModifiers, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { - // Use types.NumberValuable until custom types cannot re-implement + // Use basetypes.NumberValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.NumberValuable) + configValuable, ok := req.AttributeConfig.(basetypes.NumberValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Number Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Number attribute plan modification. "+ - "The value type must implement the types.NumberValuable interface. "+ + "The value type must implement the basetypes.NumberValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -1147,14 +1148,14 @@ func AttributePlanModifyNumber(ctx context.Context, attribute fwxschema.Attribut return } - planValuable, ok := req.AttributePlan.(types.NumberValuable) + planValuable, ok := req.AttributePlan.(basetypes.NumberValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Number Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Number attribute plan modification. "+ - "The value type must implement the types.NumberValuable interface. "+ + "The value type must implement the basetypes.NumberValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), ) @@ -1172,14 +1173,14 @@ func AttributePlanModifyNumber(ctx context.Context, attribute fwxschema.Attribut return } - stateValuable, ok := req.AttributeState.(types.NumberValuable) + stateValuable, ok := req.AttributeState.(basetypes.NumberValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Number Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Number attribute plan modification. "+ - "The value type must implement the types.NumberValuable interface. "+ + "The value type must implement the basetypes.NumberValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), ) @@ -1253,18 +1254,18 @@ func AttributePlanModifyNumber(ctx context.Context, attribute fwxschema.Attribut // AttributePlanModifyObject performs all types.Object plan modification. func AttributePlanModifyObject(ctx context.Context, attribute fwxschema.AttributeWithObjectPlanModifiers, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { - // Use types.ObjectValuable until custom types cannot re-implement + // Use basetypes.ObjectValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.ObjectValuable) + configValuable, ok := req.AttributeConfig.(basetypes.ObjectValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Object Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Object attribute plan modification. "+ - "The value type must implement the types.ObjectValuable interface. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -1282,14 +1283,14 @@ func AttributePlanModifyObject(ctx context.Context, attribute fwxschema.Attribut return } - planValuable, ok := req.AttributePlan.(types.ObjectValuable) + planValuable, ok := req.AttributePlan.(basetypes.ObjectValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Object Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Object attribute plan modification. "+ - "The value type must implement the types.ObjectValuable interface. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), ) @@ -1307,14 +1308,14 @@ func AttributePlanModifyObject(ctx context.Context, attribute fwxschema.Attribut return } - stateValuable, ok := req.AttributeState.(types.ObjectValuable) + stateValuable, ok := req.AttributeState.(basetypes.ObjectValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Object Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Object attribute plan modification. "+ - "The value type must implement the types.ObjectValuable interface. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), ) @@ -1388,18 +1389,18 @@ func AttributePlanModifyObject(ctx context.Context, attribute fwxschema.Attribut // AttributePlanModifySet performs all types.Set plan modification. func AttributePlanModifySet(ctx context.Context, attribute fwxschema.AttributeWithSetPlanModifiers, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { - // Use types.SetValuable until custom types cannot re-implement + // Use basetypes.SetValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.SetValuable) + configValuable, ok := req.AttributeConfig.(basetypes.SetValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Set Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Set attribute plan modification. "+ - "The value type must implement the types.SetValuable interface. "+ + "The value type must implement the basetypes.SetValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -1417,14 +1418,14 @@ func AttributePlanModifySet(ctx context.Context, attribute fwxschema.AttributeWi return } - planValuable, ok := req.AttributePlan.(types.SetValuable) + planValuable, ok := req.AttributePlan.(basetypes.SetValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Set Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Set attribute plan modification. "+ - "The value type must implement the types.SetValuable interface. "+ + "The value type must implement the basetypes.SetValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), ) @@ -1442,14 +1443,14 @@ func AttributePlanModifySet(ctx context.Context, attribute fwxschema.AttributeWi return } - stateValuable, ok := req.AttributeState.(types.SetValuable) + stateValuable, ok := req.AttributeState.(basetypes.SetValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Set Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Set attribute plan modification. "+ - "The value type must implement the types.SetValuable interface. "+ + "The value type must implement the basetypes.SetValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), ) @@ -1523,18 +1524,18 @@ func AttributePlanModifySet(ctx context.Context, attribute fwxschema.AttributeWi // AttributePlanModifyString performs all types.String plan modification. func AttributePlanModifyString(ctx context.Context, attribute fwxschema.AttributeWithStringPlanModifiers, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { - // Use types.StringValuable until custom types cannot re-implement + // Use basetypes.StringValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.StringValuable) + configValuable, ok := req.AttributeConfig.(basetypes.StringValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid String Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform String attribute plan modification. "+ - "The value type must implement the types.StringValuable interface. "+ + "The value type must implement the basetypes.StringValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -1552,14 +1553,14 @@ func AttributePlanModifyString(ctx context.Context, attribute fwxschema.Attribut return } - planValuable, ok := req.AttributePlan.(types.StringValuable) + planValuable, ok := req.AttributePlan.(basetypes.StringValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid String Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform String attribute plan modification. "+ - "The value type must implement the types.StringValuable interface. "+ + "The value type must implement the basetypes.StringValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), ) @@ -1577,14 +1578,14 @@ func AttributePlanModifyString(ctx context.Context, attribute fwxschema.Attribut return } - stateValuable, ok := req.AttributeState.(types.StringValuable) + stateValuable, ok := req.AttributeState.(basetypes.StringValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid String Attribute Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform String attribute plan modification. "+ - "The value type must implement the types.StringValuable interface. "+ + "The value type must implement the basetypes.StringValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), ) diff --git a/internal/fwserver/attribute_validation.go b/internal/fwserver/attribute_validation.go index 259f0fd2a..90dd6d4bc 100644 --- a/internal/fwserver/attribute_validation.go +++ b/internal/fwserver/attribute_validation.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/logging" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) // AttributeValidate performs all Attribute validation. @@ -151,18 +151,18 @@ func AttributeValidate(ctx context.Context, a fwschema.Attribute, req tfsdk.Vali // AttributeValidateBool performs all types.Bool validation. func AttributeValidateBool(ctx context.Context, attribute fwxschema.AttributeWithBoolValidators, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - // Use types.BoolValuable until custom types cannot re-implement + // Use basetypes.BoolValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.BoolValuable) + configValuable, ok := req.AttributeConfig.(basetypes.BoolValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Bool Attribute Validator Value Type", "An unexpected value type was encountered while attempting to perform Bool attribute validation. "+ - "The value type must implement the types.BoolValuable interface. "+ + "The value type must implement the basetypes.BoolValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -216,18 +216,18 @@ func AttributeValidateBool(ctx context.Context, attribute fwxschema.AttributeWit // AttributeValidateFloat64 performs all types.Float64 validation. func AttributeValidateFloat64(ctx context.Context, attribute fwxschema.AttributeWithFloat64Validators, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - // Use types.Float64Valuable until custom types cannot re-implement + // Use basetypes.Float64Valuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.Float64Valuable) + configValuable, ok := req.AttributeConfig.(basetypes.Float64Valuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Float64 Attribute Validator Value Type", "An unexpected value type was encountered while attempting to perform Float64 attribute validation. "+ - "The value type must implement the types.Float64Valuable interface. "+ + "The value type must implement the basetypes.Float64Valuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -281,18 +281,18 @@ func AttributeValidateFloat64(ctx context.Context, attribute fwxschema.Attribute // AttributeValidateInt64 performs all types.Int64 validation. func AttributeValidateInt64(ctx context.Context, attribute fwxschema.AttributeWithInt64Validators, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - // Use types.Int64Valuable until custom types cannot re-implement + // Use basetypes.Int64Valuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.Int64Valuable) + configValuable, ok := req.AttributeConfig.(basetypes.Int64Valuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Int64 Attribute Validator Value Type", "An unexpected value type was encountered while attempting to perform Int64 attribute validation. "+ - "The value type must implement the types.Int64Valuable interface. "+ + "The value type must implement the basetypes.Int64Valuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -346,18 +346,18 @@ func AttributeValidateInt64(ctx context.Context, attribute fwxschema.AttributeWi // AttributeValidateList performs all types.List validation. func AttributeValidateList(ctx context.Context, attribute fwxschema.AttributeWithListValidators, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - // Use types.ListValuable until custom types cannot re-implement + // Use basetypes.ListValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.ListValuable) + configValuable, ok := req.AttributeConfig.(basetypes.ListValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid List Attribute Validator Value Type", "An unexpected value type was encountered while attempting to perform List attribute validation. "+ - "The value type must implement the types.ListValuable interface. "+ + "The value type must implement the basetypes.ListValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -411,18 +411,18 @@ func AttributeValidateList(ctx context.Context, attribute fwxschema.AttributeWit // AttributeValidateMap performs all types.Map validation. func AttributeValidateMap(ctx context.Context, attribute fwxschema.AttributeWithMapValidators, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - // Use types.MapValuable until custom types cannot re-implement + // Use basetypes.MapValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.MapValuable) + configValuable, ok := req.AttributeConfig.(basetypes.MapValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Map Attribute Validator Value Type", "An unexpected value type was encountered while attempting to perform Map attribute validation. "+ - "The value type must implement the types.MapValuable interface. "+ + "The value type must implement the basetypes.MapValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -476,18 +476,18 @@ func AttributeValidateMap(ctx context.Context, attribute fwxschema.AttributeWith // AttributeValidateNumber performs all types.Number validation. func AttributeValidateNumber(ctx context.Context, attribute fwxschema.AttributeWithNumberValidators, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - // Use types.NumberValuable until custom types cannot re-implement + // Use basetypes.NumberValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.NumberValuable) + configValuable, ok := req.AttributeConfig.(basetypes.NumberValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Number Attribute Validator Value Type", "An unexpected value type was encountered while attempting to perform Number attribute validation. "+ - "The value type must implement the types.NumberValuable interface. "+ + "The value type must implement the basetypes.NumberValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -541,18 +541,18 @@ func AttributeValidateNumber(ctx context.Context, attribute fwxschema.AttributeW // AttributeValidateObject performs all types.Object validation. func AttributeValidateObject(ctx context.Context, attribute fwxschema.AttributeWithObjectValidators, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - // Use types.ObjectValuable until custom types cannot re-implement + // Use basetypes.ObjectValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.ObjectValuable) + configValuable, ok := req.AttributeConfig.(basetypes.ObjectValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Object Attribute Validator Value Type", "An unexpected value type was encountered while attempting to perform Object attribute validation. "+ - "The value type must implement the types.ObjectValuable interface. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -606,18 +606,18 @@ func AttributeValidateObject(ctx context.Context, attribute fwxschema.AttributeW // AttributeValidateSet performs all types.Set validation. func AttributeValidateSet(ctx context.Context, attribute fwxschema.AttributeWithSetValidators, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - // Use types.SetValuable until custom types cannot re-implement + // Use basetypes.SetValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.SetValuable) + configValuable, ok := req.AttributeConfig.(basetypes.SetValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Set Attribute Validator Value Type", "An unexpected value type was encountered while attempting to perform Set attribute validation. "+ - "The value type must implement the types.SetValuable interface. "+ + "The value type must implement the basetypes.SetValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -671,18 +671,18 @@ func AttributeValidateSet(ctx context.Context, attribute fwxschema.AttributeWith // AttributeValidateString performs all types.String validation. func AttributeValidateString(ctx context.Context, attribute fwxschema.AttributeWithStringValidators, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - // Use types.StringValuable until custom types cannot re-implement + // Use basetypes.StringValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.StringValuable) + configValuable, ok := req.AttributeConfig.(basetypes.StringValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid String Attribute Validator Value Type", "An unexpected value type was encountered while attempting to perform String attribute validation. "+ - "The value type must implement the types.StringValuable interface. "+ + "The value type must implement the basetypes.StringValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -758,14 +758,14 @@ func AttributeValidateNestedAttributes(ctx context.Context, a fwschema.Attribute nm := nestedAttribute.GetNestingMode() switch nm { case fwschema.NestingModeList: - listVal, ok := req.AttributeConfig.(types.ListValuable) + listVal, ok := req.AttributeConfig.(basetypes.ListValuable) if !ok { err := fmt.Errorf("unknown attribute value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) resp.Diagnostics.AddAttributeError( req.AttributePath, "Attribute Validation Error Invalid Value Type", - "A type that implements types.ListValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + "A type that implements basetypes.ListValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), ) return @@ -792,14 +792,14 @@ func AttributeValidateNestedAttributes(ctx context.Context, a fwschema.Attribute resp.Diagnostics.Append(nestedAttributeObjectResp.Diagnostics...) } case fwschema.NestingModeSet: - setVal, ok := req.AttributeConfig.(types.SetValuable) + setVal, ok := req.AttributeConfig.(basetypes.SetValuable) if !ok { err := fmt.Errorf("unknown attribute value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) resp.Diagnostics.AddAttributeError( req.AttributePath, "Attribute Validation Error Invalid Value Type", - "A type that implements types.SetValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + "A type that implements basetypes.SetValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), ) return @@ -826,14 +826,14 @@ func AttributeValidateNestedAttributes(ctx context.Context, a fwschema.Attribute resp.Diagnostics.Append(nestedAttributeObjectResp.Diagnostics...) } case fwschema.NestingModeMap: - mapVal, ok := req.AttributeConfig.(types.MapValuable) + mapVal, ok := req.AttributeConfig.(basetypes.MapValuable) if !ok { err := fmt.Errorf("unknown attribute value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) resp.Diagnostics.AddAttributeError( req.AttributePath, "Attribute Validation Error Invalid Value Type", - "A type that implements types.MapValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + "A type that implements basetypes.MapValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), ) return @@ -860,14 +860,14 @@ func AttributeValidateNestedAttributes(ctx context.Context, a fwschema.Attribute resp.Diagnostics.Append(nestedAttributeObjectResp.Diagnostics...) } case fwschema.NestingModeSingle: - objectVal, ok := req.AttributeConfig.(types.ObjectValuable) + objectVal, ok := req.AttributeConfig.(basetypes.ObjectValuable) if !ok { err := fmt.Errorf("unknown attribute value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) resp.Diagnostics.AddAttributeError( req.AttributePath, "Attribute Validation Error Invalid Value Type", - "A type that implements types.ObjectValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + "A type that implements basetypes.ObjectValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), ) return @@ -911,7 +911,7 @@ func NestedAttributeObjectValidate(ctx context.Context, o fwschema.NestedAttribu objectWithValidators, ok := o.(fwxschema.NestedAttributeObjectWithValidators) if ok { - objectVal, ok := req.AttributeConfig.(types.ObjectValuable) + objectVal, ok := req.AttributeConfig.(basetypes.ObjectValuable) if !ok { resp.Diagnostics.AddAttributeError( diff --git a/internal/fwserver/block_plan_modification.go b/internal/fwserver/block_plan_modification.go index d6219f24d..944fc2b08 100644 --- a/internal/fwserver/block_plan_modification.go +++ b/internal/fwserver/block_plan_modification.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) // BlockModifyPlan performs all Block plan modification. @@ -309,18 +310,18 @@ func BlockModifyPlan(ctx context.Context, b fwschema.Block, req tfsdk.ModifyAttr // BlockPlanModifyList performs all types.List plan modification. func BlockPlanModifyList(ctx context.Context, block fwxschema.BlockWithListPlanModifiers, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { - // Use types.ListValuable until custom types cannot re-implement + // Use basetypes.ListValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.ListValuable) + configValuable, ok := req.AttributeConfig.(basetypes.ListValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid List Block Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform List block plan modification. "+ - "The value type must implement the types.ListValuable interface. "+ + "The value type must implement the basetypes.ListValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -338,14 +339,14 @@ func BlockPlanModifyList(ctx context.Context, block fwxschema.BlockWithListPlanM return } - planValuable, ok := req.AttributePlan.(types.ListValuable) + planValuable, ok := req.AttributePlan.(basetypes.ListValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid List Block Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform List block plan modification. "+ - "The value type must implement the types.ListValuable interface. "+ + "The value type must implement the basetypes.ListValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), ) @@ -363,14 +364,14 @@ func BlockPlanModifyList(ctx context.Context, block fwxschema.BlockWithListPlanM return } - stateValuable, ok := req.AttributeState.(types.ListValuable) + stateValuable, ok := req.AttributeState.(basetypes.ListValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid List Block Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform List block plan modification. "+ - "The value type must implement the types.ListValuable interface. "+ + "The value type must implement the basetypes.ListValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), ) @@ -444,18 +445,18 @@ func BlockPlanModifyList(ctx context.Context, block fwxschema.BlockWithListPlanM // BlockPlanModifyObject performs all types.Object plan modification. func BlockPlanModifyObject(ctx context.Context, block fwxschema.BlockWithObjectPlanModifiers, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { - // Use types.ObjectValuable until custom types cannot re-implement + // Use basetypes.ObjectValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.ObjectValuable) + configValuable, ok := req.AttributeConfig.(basetypes.ObjectValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Object Block Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Object block plan modification. "+ - "The value type must implement the types.ObjectValuable interface. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -473,14 +474,14 @@ func BlockPlanModifyObject(ctx context.Context, block fwxschema.BlockWithObjectP return } - planValuable, ok := req.AttributePlan.(types.ObjectValuable) + planValuable, ok := req.AttributePlan.(basetypes.ObjectValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Object Block Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Object block plan modification. "+ - "The value type must implement the types.ObjectValuable interface. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), ) @@ -498,14 +499,14 @@ func BlockPlanModifyObject(ctx context.Context, block fwxschema.BlockWithObjectP return } - stateValuable, ok := req.AttributeState.(types.ObjectValuable) + stateValuable, ok := req.AttributeState.(basetypes.ObjectValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Object Block Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Object block plan modification. "+ - "The value type must implement the types.ObjectValuable interface. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), ) @@ -579,18 +580,18 @@ func BlockPlanModifyObject(ctx context.Context, block fwxschema.BlockWithObjectP // BlockPlanModifySet performs all types.Set plan modification. func BlockPlanModifySet(ctx context.Context, block fwxschema.BlockWithSetPlanModifiers, req tfsdk.ModifyAttributePlanRequest, resp *ModifyAttributePlanResponse) { - // Use types.SetValuable until custom types cannot re-implement + // Use basetypes.SetValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.SetValuable) + configValuable, ok := req.AttributeConfig.(basetypes.SetValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Set Block Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Set block plan modification. "+ - "The value type must implement the types.SetValuable interface. "+ + "The value type must implement the basetypes.SetValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -608,14 +609,14 @@ func BlockPlanModifySet(ctx context.Context, block fwxschema.BlockWithSetPlanMod return } - planValuable, ok := req.AttributePlan.(types.SetValuable) + planValuable, ok := req.AttributePlan.(basetypes.SetValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Set Block Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Set block plan modification. "+ - "The value type must implement the types.SetValuable interface. "+ + "The value type must implement the basetypes.SetValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributePlan), ) @@ -633,14 +634,14 @@ func BlockPlanModifySet(ctx context.Context, block fwxschema.BlockWithSetPlanMod return } - stateValuable, ok := req.AttributeState.(types.SetValuable) + stateValuable, ok := req.AttributeState.(basetypes.SetValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Set Block Plan Modifier Value Type", "An unexpected value type was encountered while attempting to perform Set block plan modification. "+ - "The value type must implement the types.SetValuable interface. "+ + "The value type must implement the basetypes.SetValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeState), ) diff --git a/internal/fwserver/block_plan_modification_test.go b/internal/fwserver/block_plan_modification_test.go index 388d6bcff..7561e6664 100644 --- a/internal/fwserver/block_plan_modification_test.go +++ b/internal/fwserver/block_plan_modification_test.go @@ -21,6 +21,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/tfsdk" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) func TestBlockModifyPlan(t *testing.T) { @@ -5624,7 +5625,7 @@ func TestNestedBlockObjectPlanModify(t *testing.T) { type testBlockPlanModifierNullList struct{} func (t testBlockPlanModifierNullList) Modify(ctx context.Context, req tfsdk.ModifyAttributePlanRequest, resp *tfsdk.ModifyAttributePlanResponse) { - _, ok := req.AttributePlan.(types.ListValuable) + _, ok := req.AttributePlan.(basetypes.ListValuable) if !ok { return } diff --git a/internal/fwserver/block_validation.go b/internal/fwserver/block_validation.go index 24998d696..6fc725220 100644 --- a/internal/fwserver/block_validation.go +++ b/internal/fwserver/block_validation.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/tfsdk" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) // BlockValidate performs all Block validation. @@ -71,14 +71,14 @@ func BlockValidate(ctx context.Context, b fwschema.Block, req tfsdk.ValidateAttr nm := b.GetNestingMode() switch nm { case fwschema.BlockNestingModeList: - listVal, ok := req.AttributeConfig.(types.ListValuable) + listVal, ok := req.AttributeConfig.(basetypes.ListValuable) if !ok { err := fmt.Errorf("unknown block value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) resp.Diagnostics.AddAttributeError( req.AttributePath, "Block Validation Error Invalid Value Type", - "A type that implements types.ListValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + "A type that implements basetypes.ListValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), ) return @@ -128,14 +128,14 @@ func BlockValidate(ctx context.Context, b fwschema.Block, req tfsdk.ValidateAttr resp.Diagnostics.Append(blockMinItemsDiagnostic(req.AttributePath, b.GetMinItems(), len(l.Elements()))) } case fwschema.BlockNestingModeSet: - setVal, ok := req.AttributeConfig.(types.SetValuable) + setVal, ok := req.AttributeConfig.(basetypes.SetValuable) if !ok { err := fmt.Errorf("unknown block value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) resp.Diagnostics.AddAttributeError( req.AttributePath, "Block Validation Error Invalid Value Type", - "A type that implements types.SetValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + "A type that implements basetypes.SetValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), ) return @@ -185,14 +185,14 @@ func BlockValidate(ctx context.Context, b fwschema.Block, req tfsdk.ValidateAttr resp.Diagnostics.Append(blockMinItemsDiagnostic(req.AttributePath, b.GetMinItems(), len(s.Elements()))) } case fwschema.BlockNestingModeSingle: - objectVal, ok := req.AttributeConfig.(types.ObjectValuable) + objectVal, ok := req.AttributeConfig.(basetypes.ObjectValuable) if !ok { err := fmt.Errorf("unknown block value type (%T) for nesting mode (%T) at path: %s", req.AttributeConfig, nm, req.AttributePath) resp.Diagnostics.AddAttributeError( req.AttributePath, "Block Validation Error Invalid Value Type", - "A type that implements types.ObjectValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), + "A type that implements basetypes.ObjectValuable is expected here. Report this to the provider developer:\n\n"+err.Error(), ) return @@ -243,18 +243,18 @@ func BlockValidate(ctx context.Context, b fwschema.Block, req tfsdk.ValidateAttr // BlockValidateList performs all types.List validation. func BlockValidateList(ctx context.Context, block fwxschema.BlockWithListValidators, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - // Use types.ListValuable until custom types cannot re-implement + // Use basetypes.ListValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.ListValuable) + configValuable, ok := req.AttributeConfig.(basetypes.ListValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid List Attribute Validator Value Type", "An unexpected value type was encountered while attempting to perform List attribute validation. "+ - "The value type must implement the types.ListValuable interface. "+ + "The value type must implement the basetypes.ListValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -308,18 +308,18 @@ func BlockValidateList(ctx context.Context, block fwxschema.BlockWithListValidat // BlockValidateObject performs all types.Object validation. func BlockValidateObject(ctx context.Context, block fwxschema.BlockWithObjectValidators, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - // Use types.ObjectValuable until custom types cannot re-implement + // Use basetypes.ObjectValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.ObjectValuable) + configValuable, ok := req.AttributeConfig.(basetypes.ObjectValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Object Attribute Validator Value Type", "An unexpected value type was encountered while attempting to perform Object attribute validation. "+ - "The value type must implement the types.ObjectValuable interface. "+ + "The value type must implement the basetypes.ObjectValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -373,18 +373,18 @@ func BlockValidateObject(ctx context.Context, block fwxschema.BlockWithObjectVal // BlockValidateSet performs all types.Set validation. func BlockValidateSet(ctx context.Context, block fwxschema.BlockWithSetValidators, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) { - // Use types.SetValuable until custom types cannot re-implement + // Use basetypes.SetValuable until custom types cannot re-implement // ValueFromTerraform. Until then, custom types are not technically // required to implement this interface. This opts to enforce the // requirement before compatibility promises would interfere. - configValuable, ok := req.AttributeConfig.(types.SetValuable) + configValuable, ok := req.AttributeConfig.(basetypes.SetValuable) if !ok { resp.Diagnostics.AddAttributeError( req.AttributePath, "Invalid Set Attribute Validator Value Type", "An unexpected value type was encountered while attempting to perform Set attribute validation. "+ - "The value type must implement the types.SetValuable interface. "+ + "The value type must implement the basetypes.SetValuable interface. "+ "Please report this to the provider developers.\n\n"+ fmt.Sprintf("Incoming Value Type: %T", req.AttributeConfig), ) @@ -440,7 +440,7 @@ func NestedBlockObjectValidate(ctx context.Context, o fwschema.NestedBlockObject objectWithValidators, ok := o.(fwxschema.NestedBlockObjectWithValidators) if ok { - objectVal, ok := req.AttributeConfig.(types.ObjectValuable) + objectVal, ok := req.AttributeConfig.(basetypes.ObjectValuable) if !ok { resp.Diagnostics.AddAttributeError( diff --git a/internal/reflect/build_value_test.go b/internal/reflect/build_value_test.go index ebf36e75e..83c677a69 100644 --- a/internal/reflect/build_value_test.go +++ b/internal/reflect/build_value_test.go @@ -29,7 +29,7 @@ func TestBuildValue(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received null value, however the target type cannot handle null values. Use the corresponding `types` package type, a pointer type or a custom type that handles null values.\n\n"+ - "Path: id\nTarget Type: string\nSuggested `types` Type: types.String\nSuggested Pointer Type: *string", + "Path: id\nTarget Type: string\nSuggested `types` Type: basetypes.StringValue\nSuggested Pointer Type: *string", ), }, }, @@ -41,7 +41,7 @@ func TestBuildValue(t *testing.T) { "Value Conversion Error", "An unexpected error was encountered trying to build a value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ "Received unknown value, however the target type cannot handle unknown values. Use the corresponding `types` package type or a custom type that handles unknown values.\n\n"+ - "Path: id\nTarget Type: string\nSuggested Type: types.String", + "Path: id\nTarget Type: string\nSuggested Type: basetypes.StringValue", ), }, }, diff --git a/internal/testing/testschema/nested_attribute_object.go b/internal/testing/testschema/nested_attribute_object.go index d743406fa..f0d0b805c 100644 --- a/internal/testing/testschema/nested_attribute_object.go +++ b/internal/testing/testschema/nested_attribute_object.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -66,7 +67,7 @@ func (o NestedAttributeObject) GetAttributes() fwschema.UnderlyingAttributes { } // Type returns the framework type of the NestedAttributeObject. -func (o NestedAttributeObject) Type() types.ObjectTypable { +func (o NestedAttributeObject) Type() basetypes.ObjectTypable { attrTypes := make(map[string]attr.Type, len(o.Attributes)) for name, attribute := range o.Attributes { diff --git a/internal/testing/testschema/nested_attribute_object_with_planmodifiers.go b/internal/testing/testschema/nested_attribute_object_with_planmodifiers.go index 0cadd7660..7f5612e23 100644 --- a/internal/testing/testschema/nested_attribute_object_with_planmodifiers.go +++ b/internal/testing/testschema/nested_attribute_object_with_planmodifiers.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -74,7 +75,7 @@ func (o NestedAttributeObjectWithPlanModifiers) ObjectPlanModifiers() []planmodi } // Type returns the framework type of the NestedAttributeObjectWithPlanModifiers. -func (o NestedAttributeObjectWithPlanModifiers) Type() types.ObjectTypable { +func (o NestedAttributeObjectWithPlanModifiers) Type() basetypes.ObjectTypable { attrTypes := make(map[string]attr.Type, len(o.Attributes)) for name, attribute := range o.Attributes { diff --git a/internal/testing/testschema/nested_attribute_object_with_validators.go b/internal/testing/testschema/nested_attribute_object_with_validators.go index c724f607b..39cf3e14e 100644 --- a/internal/testing/testschema/nested_attribute_object_with_validators.go +++ b/internal/testing/testschema/nested_attribute_object_with_validators.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -74,7 +75,7 @@ func (o NestedAttributeObjectWithValidators) ObjectValidators() []validator.Obje } // Type returns the framework type of the NestedAttributeObjectWithValidators. -func (o NestedAttributeObjectWithValidators) Type() types.ObjectTypable { +func (o NestedAttributeObjectWithValidators) Type() basetypes.ObjectTypable { attrTypes := make(map[string]attr.Type, len(o.Attributes)) for name, attribute := range o.Attributes { diff --git a/internal/testing/testschema/nested_block_object.go b/internal/testing/testschema/nested_block_object.go index e978c07ee..dc5d4f8d5 100644 --- a/internal/testing/testschema/nested_block_object.go +++ b/internal/testing/testschema/nested_block_object.go @@ -2,7 +2,7 @@ package testschema import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -40,6 +40,6 @@ func (o NestedBlockObject) GetBlocks() map[string]fwschema.Block { } // Type returns the framework type of the NestedBlockObject. -func (o NestedBlockObject) Type() types.ObjectTypable { +func (o NestedBlockObject) Type() basetypes.ObjectTypable { return fwschema.NestedBlockObjectType(o) } diff --git a/internal/testing/testschema/nested_block_object_with_plan_modifiers.go b/internal/testing/testschema/nested_block_object_with_plan_modifiers.go index ba3c23d85..f9a2c737a 100644 --- a/internal/testing/testschema/nested_block_object_with_plan_modifiers.go +++ b/internal/testing/testschema/nested_block_object_with_plan_modifiers.go @@ -4,7 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -48,6 +48,6 @@ func (o NestedBlockObjectWithPlanModifiers) ObjectPlanModifiers() []planmodifier } // Type returns the framework type of the NestedBlockObjectWithPlanModifiers. -func (o NestedBlockObjectWithPlanModifiers) Type() types.ObjectTypable { +func (o NestedBlockObjectWithPlanModifiers) Type() basetypes.ObjectTypable { return fwschema.NestedBlockObjectType(o) } diff --git a/internal/testing/testschema/nested_block_object_with_validators.go b/internal/testing/testschema/nested_block_object_with_validators.go index bc0042b21..9a227f496 100644 --- a/internal/testing/testschema/nested_block_object_with_validators.go +++ b/internal/testing/testschema/nested_block_object_with_validators.go @@ -4,7 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -48,6 +48,6 @@ func (o NestedBlockObjectWithValidators) ObjectValidators() []validator.Object { } // Type returns the framework type of the NestedBlockObjectWithValidators. -func (o NestedBlockObjectWithValidators) Type() types.ObjectTypable { +func (o NestedBlockObjectWithValidators) Type() basetypes.ObjectTypable { return fwschema.NestedBlockObjectType(o) } diff --git a/internal/testing/types/bool.go b/internal/testing/types/bool.go index e125d34f7..20954e36e 100644 --- a/internal/testing/types/bool.go +++ b/internal/testing/types/bool.go @@ -7,12 +7,13 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) var ( - _ types.BoolTypable = BoolType{} - _ types.BoolValuable = Bool{} + _ basetypes.BoolTypable = BoolType{} + _ basetypes.BoolValuable = Bool{} ) // BoolType is a reimplementation of types.BoolType that can be used as a base @@ -39,7 +40,7 @@ func (t BoolType) TerraformType(_ context.Context) tftypes.Type { return tftypes.Bool } -func (t BoolType) ValueFromBool(ctx context.Context, in types.Bool) (types.BoolValuable, diag.Diagnostics) { +func (t BoolType) ValueFromBool(ctx context.Context, in basetypes.BoolValue) (basetypes.BoolValuable, diag.Diagnostics) { if in.IsNull() { return Bool{ Bool: types.BoolNull(), diff --git a/internal/testing/types/listnestedattributescustom.go b/internal/testing/types/listnestedattributescustom.go index 91d3178e8..119d54d75 100644 --- a/internal/testing/types/listnestedattributescustom.go +++ b/internal/testing/types/listnestedattributescustom.go @@ -9,11 +9,12 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) var ( - _ types.ListTypable = ListNestedAttributesCustomTypeType{} - _ types.ListValuable = &ListNestedAttributesCustomValue{} + _ basetypes.ListTypable = ListNestedAttributesCustomTypeType{} + _ basetypes.ListValuable = &ListNestedAttributesCustomValue{} ) type ListNestedAttributesCustomType struct { diff --git a/internal/testing/types/mapnestedattributescustom.go b/internal/testing/types/mapnestedattributescustom.go index facef9032..d95eb62f4 100644 --- a/internal/testing/types/mapnestedattributescustom.go +++ b/internal/testing/types/mapnestedattributescustom.go @@ -9,11 +9,12 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) var ( - _ types.MapTypable = MapNestedAttributesCustomTypeType{} - _ types.MapValuable = &MapNestedAttributesCustomValue{} + _ basetypes.MapTypable = MapNestedAttributesCustomTypeType{} + _ basetypes.MapValuable = &MapNestedAttributesCustomValue{} ) type MapNestedAttributesCustomType struct { diff --git a/internal/testing/types/number.go b/internal/testing/types/number.go index 0b08f9f12..fa8118371 100644 --- a/internal/testing/types/number.go +++ b/internal/testing/types/number.go @@ -8,12 +8,13 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) var ( - _ types.NumberTypable = NumberType{} - _ types.NumberValuable = Number{} + _ basetypes.NumberTypable = NumberType{} + _ basetypes.NumberValuable = Number{} ) // NumberType is a reimplementation of types.NumberType that can be used as a base @@ -40,7 +41,7 @@ func (t NumberType) TerraformType(_ context.Context) tftypes.Type { return tftypes.Number } -func (t NumberType) ValueFromNumber(ctx context.Context, in types.Number) (types.NumberValuable, diag.Diagnostics) { +func (t NumberType) ValueFromNumber(ctx context.Context, in basetypes.NumberValue) (basetypes.NumberValuable, diag.Diagnostics) { if in.IsNull() { return Number{ Number: types.NumberNull(), diff --git a/internal/testing/types/setnestedattributescustom.go b/internal/testing/types/setnestedattributescustom.go index 5751ffabd..512915fed 100644 --- a/internal/testing/types/setnestedattributescustom.go +++ b/internal/testing/types/setnestedattributescustom.go @@ -9,11 +9,12 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) var ( - _ types.SetTypable = SetNestedAttributesCustomTypeType{} - _ types.SetValuable = &SetNestedAttributesCustomValue{} + _ basetypes.SetTypable = SetNestedAttributesCustomTypeType{} + _ basetypes.SetValuable = &SetNestedAttributesCustomValue{} ) type SetNestedAttributesCustomType struct { diff --git a/internal/testing/types/singlenestedattributescustom.go b/internal/testing/types/singlenestedattributescustom.go index ff3654c65..792fc0d79 100644 --- a/internal/testing/types/singlenestedattributescustom.go +++ b/internal/testing/types/singlenestedattributescustom.go @@ -9,11 +9,12 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) var ( - _ types.SetTypable = SetNestedAttributesCustomTypeType{} - _ types.SetValuable = &SetNestedAttributesCustomValue{} + _ basetypes.SetTypable = SetNestedAttributesCustomTypeType{} + _ basetypes.SetValuable = &SetNestedAttributesCustomValue{} ) type SingleNestedAttributesCustomType struct { diff --git a/internal/testing/types/string.go b/internal/testing/types/string.go index 3da5a1fc9..6b196e8eb 100644 --- a/internal/testing/types/string.go +++ b/internal/testing/types/string.go @@ -7,12 +7,13 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) var ( - _ types.StringTypable = StringType{} - _ types.StringValuable = String{} + _ basetypes.StringTypable = StringType{} + _ basetypes.StringValuable = String{} ) // StringType is a reimplementation of types.StringType that can be used as a base @@ -39,7 +40,7 @@ func (t StringType) TerraformType(_ context.Context) tftypes.Type { return tftypes.String } -func (t StringType) ValueFromString(ctx context.Context, in types.String) (types.StringValuable, diag.Diagnostics) { +func (t StringType) ValueFromString(ctx context.Context, in basetypes.StringValue) (basetypes.StringValuable, diag.Diagnostics) { if in.IsNull() { return String{ InternalString: types.StringNull(), diff --git a/provider/metaschema/bool_attribute.go b/provider/metaschema/bool_attribute.go index fc1b179fc..f3c45d452 100644 --- a/provider/metaschema/bool_attribute.go +++ b/provider/metaschema/bool_attribute.go @@ -4,6 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -26,9 +27,9 @@ var ( // .example_attribute type BoolAttribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.BoolType. When retrieving data, the types.BoolValuable + // default basetypes.BoolType. When retrieving data, the basetypes.BoolValuable // associated with this custom type must be used in place of types.Bool. - CustomType types.BoolTypable + CustomType basetypes.BoolTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/bool_attribute_test.go b/provider/metaschema/bool_attribute_test.go index c389a6f3a..3f2313cde 100644 --- a/provider/metaschema/bool_attribute_test.go +++ b/provider/metaschema/bool_attribute_test.go @@ -28,25 +28,25 @@ func TestBoolAttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: metaschema.BoolAttribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.BoolType"), }, "ElementKeyInt": { attribute: metaschema.BoolAttribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.BoolType"), }, "ElementKeyString": { attribute: metaschema.BoolAttribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.BoolType"), }, "ElementKeyValue": { attribute: metaschema.BoolAttribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.BoolType"), }, } diff --git a/provider/metaschema/float64_attribute.go b/provider/metaschema/float64_attribute.go index 99fea520c..77c556f7e 100644 --- a/provider/metaschema/float64_attribute.go +++ b/provider/metaschema/float64_attribute.go @@ -4,6 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -29,9 +30,9 @@ var ( // .example_attribute type Float64Attribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.Float64Type. When retrieving data, the types.Float64Valuable + // default basetypes.Float64Type. When retrieving data, the basetypes.Float64Valuable // associated with this custom type must be used in place of types.Float64. - CustomType types.Float64Typable + CustomType basetypes.Float64Typable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/float64_attribute_test.go b/provider/metaschema/float64_attribute_test.go index a553c49d2..73314b20e 100644 --- a/provider/metaschema/float64_attribute_test.go +++ b/provider/metaschema/float64_attribute_test.go @@ -27,25 +27,25 @@ func TestFloat64AttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: metaschema.Float64Attribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.Float64Type"), }, "ElementKeyInt": { attribute: metaschema.Float64Attribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.Float64Type"), }, "ElementKeyString": { attribute: metaschema.Float64Attribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.Float64Type"), }, "ElementKeyValue": { attribute: metaschema.Float64Attribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.Float64Type"), }, } diff --git a/provider/metaschema/int64_attribute.go b/provider/metaschema/int64_attribute.go index 08eed4fc8..2ad6216f7 100644 --- a/provider/metaschema/int64_attribute.go +++ b/provider/metaschema/int64_attribute.go @@ -4,6 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -29,9 +30,9 @@ var ( // .example_attribute type Int64Attribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.Int64Type. When retrieving data, the types.Int64Valuable + // default basetypes.Int64Type. When retrieving data, the basetypes.Int64Valuable // associated with this custom type must be used in place of types.Int64. - CustomType types.Int64Typable + CustomType basetypes.Int64Typable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/int64_attribute_test.go b/provider/metaschema/int64_attribute_test.go index 26f318529..822c645ad 100644 --- a/provider/metaschema/int64_attribute_test.go +++ b/provider/metaschema/int64_attribute_test.go @@ -27,25 +27,25 @@ func TestInt64AttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: metaschema.Int64Attribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.Int64Type"), }, "ElementKeyInt": { attribute: metaschema.Int64Attribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.Int64Type"), }, "ElementKeyString": { attribute: metaschema.Int64Attribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.Int64Type"), }, "ElementKeyValue": { attribute: metaschema.Int64Attribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.Int64Type"), }, } diff --git a/provider/metaschema/list_attribute.go b/provider/metaschema/list_attribute.go index 99d1877a6..3fc662627 100644 --- a/provider/metaschema/list_attribute.go +++ b/provider/metaschema/list_attribute.go @@ -4,6 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -37,9 +38,9 @@ type ListAttribute struct { ElementType attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.ListType. When retrieving data, the types.ListValuable + // default basetypes.ListType. When retrieving data, the basetypes.ListValuable // associated with this custom type must be used in place of types.List. - CustomType types.ListTypable + CustomType basetypes.ListTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/list_nested_attribute.go b/provider/metaschema/list_nested_attribute.go index 5afc97bd4..29146a0a1 100644 --- a/provider/metaschema/list_nested_attribute.go +++ b/provider/metaschema/list_nested_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -48,9 +49,9 @@ type ListNestedAttribute struct { // CustomType enables the use of a custom attribute type in place of the // default types.ListType of types.ObjectType. When retrieving data, the - // types.ListValuable associated with this custom type must be used in + // basetypes.ListValuable associated with this custom type must be used in // place of types.List. - CustomType types.ListTypable + CustomType basetypes.ListTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/map_attribute.go b/provider/metaschema/map_attribute.go index 5fa891dfc..839ea9e4d 100644 --- a/provider/metaschema/map_attribute.go +++ b/provider/metaschema/map_attribute.go @@ -4,6 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -40,9 +41,9 @@ type MapAttribute struct { ElementType attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.MapType. When retrieving data, the types.MapValuable + // default basetypes.MapType. When retrieving data, the basetypes.MapValuable // associated with this custom type must be used in place of types.Map. - CustomType types.MapTypable + CustomType basetypes.MapTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/map_nested_attribute.go b/provider/metaschema/map_nested_attribute.go index 5a8781db3..518ec0c82 100644 --- a/provider/metaschema/map_nested_attribute.go +++ b/provider/metaschema/map_nested_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -48,9 +49,9 @@ type MapNestedAttribute struct { // CustomType enables the use of a custom attribute type in place of the // default types.MapType of types.ObjectType. When retrieving data, the - // types.MapValuable associated with this custom type must be used in + // basetypes.MapValuable associated with this custom type must be used in // place of types.Map. - CustomType types.MapTypable + CustomType basetypes.MapTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/nested_attribute_object.go b/provider/metaschema/nested_attribute_object.go index a893f6c3c..4755b0187 100644 --- a/provider/metaschema/nested_attribute_object.go +++ b/provider/metaschema/nested_attribute_object.go @@ -2,7 +2,7 @@ package metaschema import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -25,9 +25,9 @@ type NestedAttributeObject struct { Attributes map[string]Attribute // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable } // ApplyTerraform5AttributePathStep performs an AttributeName step on the @@ -51,7 +51,7 @@ func (o NestedAttributeObject) GetAttributes() fwschema.UnderlyingAttributes { } // Type returns the framework type of the NestedAttributeObject. -func (o NestedAttributeObject) Type() types.ObjectTypable { +func (o NestedAttributeObject) Type() basetypes.ObjectTypable { if o.CustomType != nil { return o.CustomType } diff --git a/provider/metaschema/number_attribute.go b/provider/metaschema/number_attribute.go index 8c99edc51..039cfdc0e 100644 --- a/provider/metaschema/number_attribute.go +++ b/provider/metaschema/number_attribute.go @@ -4,6 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -30,9 +31,9 @@ var ( // .example_attribute type NumberAttribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.NumberType. When retrieving data, the types.NumberValuable + // default basetypes.NumberType. When retrieving data, the basetypes.NumberValuable // associated with this custom type must be used in place of types.Number. - CustomType types.NumberTypable + CustomType basetypes.NumberTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/number_attribute_test.go b/provider/metaschema/number_attribute_test.go index fba9c3546..84c0a6076 100644 --- a/provider/metaschema/number_attribute_test.go +++ b/provider/metaschema/number_attribute_test.go @@ -28,25 +28,25 @@ func TestNumberAttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: metaschema.NumberAttribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.NumberType"), }, "ElementKeyInt": { attribute: metaschema.NumberAttribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.NumberType"), }, "ElementKeyString": { attribute: metaschema.NumberAttribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.NumberType"), }, "ElementKeyValue": { attribute: metaschema.NumberAttribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.NumberType"), }, } diff --git a/provider/metaschema/object_attribute.go b/provider/metaschema/object_attribute.go index 954fd72e7..dfb9f91cb 100644 --- a/provider/metaschema/object_attribute.go +++ b/provider/metaschema/object_attribute.go @@ -4,6 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -39,9 +40,9 @@ type ObjectAttribute struct { AttributeTypes map[string]attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/set_attribute.go b/provider/metaschema/set_attribute.go index 7261145e2..661ca85bb 100644 --- a/provider/metaschema/set_attribute.go +++ b/provider/metaschema/set_attribute.go @@ -4,6 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -35,9 +36,9 @@ type SetAttribute struct { ElementType attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.SetType. When retrieving data, the types.SetValuable + // default basetypes.SetType. When retrieving data, the basetypes.SetValuable // associated with this custom type must be used in place of types.Set. - CustomType types.SetTypable + CustomType basetypes.SetTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/set_nested_attribute.go b/provider/metaschema/set_nested_attribute.go index d3cc9f69f..9f9f2b9cb 100644 --- a/provider/metaschema/set_nested_attribute.go +++ b/provider/metaschema/set_nested_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -43,9 +44,9 @@ type SetNestedAttribute struct { // CustomType enables the use of a custom attribute type in place of the // default types.SetType of types.ObjectType. When retrieving data, the - // types.SetValuable associated with this custom type must be used in + // basetypes.SetValuable associated with this custom type must be used in // place of types.Set. - CustomType types.SetTypable + CustomType basetypes.SetTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/single_nested_attribute.go b/provider/metaschema/single_nested_attribute.go index 58c0105e6..c204a2ad9 100644 --- a/provider/metaschema/single_nested_attribute.go +++ b/provider/metaschema/single_nested_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -42,9 +43,9 @@ type SingleNestedAttribute struct { Attributes map[string]Attribute // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/string_attribute.go b/provider/metaschema/string_attribute.go index bf5da78b0..293b4d211 100644 --- a/provider/metaschema/string_attribute.go +++ b/provider/metaschema/string_attribute.go @@ -4,6 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -26,9 +27,9 @@ var ( // .example_attribute type StringAttribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.StringType. When retrieving data, the types.StringValuable + // default basetypes.StringType. When retrieving data, the basetypes.StringValuable // associated with this custom type must be used in place of types.String. - CustomType types.StringTypable + CustomType basetypes.StringTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/metaschema/string_attribute_test.go b/provider/metaschema/string_attribute_test.go index ef150c1e9..566cdf58f 100644 --- a/provider/metaschema/string_attribute_test.go +++ b/provider/metaschema/string_attribute_test.go @@ -28,25 +28,25 @@ func TestStringAttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: metaschema.StringAttribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.StringType"), }, "ElementKeyInt": { attribute: metaschema.StringAttribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.StringType"), }, "ElementKeyString": { attribute: metaschema.StringAttribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.StringType"), }, "ElementKeyValue": { attribute: metaschema.StringAttribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.StringType"), }, } diff --git a/provider/schema/bool_attribute.go b/provider/schema/bool_attribute.go index 43d7d9223..185563860 100644 --- a/provider/schema/bool_attribute.go +++ b/provider/schema/bool_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -29,9 +30,9 @@ var ( // .example_attribute type BoolAttribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.BoolType. When retrieving data, the types.BoolValuable + // default basetypes.BoolType. When retrieving data, the basetypes.BoolValuable // associated with this custom type must be used in place of types.Bool. - CustomType types.BoolTypable + CustomType basetypes.BoolTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/bool_attribute_test.go b/provider/schema/bool_attribute_test.go index 1802af444..e30aa072d 100644 --- a/provider/schema/bool_attribute_test.go +++ b/provider/schema/bool_attribute_test.go @@ -29,25 +29,25 @@ func TestBoolAttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.BoolAttribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.BoolType"), }, "ElementKeyInt": { attribute: schema.BoolAttribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.BoolType"), }, "ElementKeyString": { attribute: schema.BoolAttribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.BoolType"), }, "ElementKeyValue": { attribute: schema.BoolAttribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.BoolType"), }, } diff --git a/provider/schema/float64_attribute.go b/provider/schema/float64_attribute.go index d4857e158..1f89f928e 100644 --- a/provider/schema/float64_attribute.go +++ b/provider/schema/float64_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -32,9 +33,9 @@ var ( // .example_attribute type Float64Attribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.Float64Type. When retrieving data, the types.Float64Valuable + // default basetypes.Float64Type. When retrieving data, the basetypes.Float64Valuable // associated with this custom type must be used in place of types.Float64. - CustomType types.Float64Typable + CustomType basetypes.Float64Typable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/float64_attribute_test.go b/provider/schema/float64_attribute_test.go index 2bf4d630c..ff86478d3 100644 --- a/provider/schema/float64_attribute_test.go +++ b/provider/schema/float64_attribute_test.go @@ -28,25 +28,25 @@ func TestFloat64AttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.Float64Attribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.Float64Type"), }, "ElementKeyInt": { attribute: schema.Float64Attribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.Float64Type"), }, "ElementKeyString": { attribute: schema.Float64Attribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.Float64Type"), }, "ElementKeyValue": { attribute: schema.Float64Attribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.Float64Type"), }, } diff --git a/provider/schema/int64_attribute.go b/provider/schema/int64_attribute.go index 5e7b0934d..b9741700b 100644 --- a/provider/schema/int64_attribute.go +++ b/provider/schema/int64_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -32,9 +33,9 @@ var ( // .example_attribute type Int64Attribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.Int64Type. When retrieving data, the types.Int64Valuable + // default basetypes.Int64Type. When retrieving data, the basetypes.Int64Valuable // associated with this custom type must be used in place of types.Int64. - CustomType types.Int64Typable + CustomType basetypes.Int64Typable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/int64_attribute_test.go b/provider/schema/int64_attribute_test.go index ffc4e86c4..2c1b21d5a 100644 --- a/provider/schema/int64_attribute_test.go +++ b/provider/schema/int64_attribute_test.go @@ -28,25 +28,25 @@ func TestInt64AttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.Int64Attribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.Int64Type"), }, "ElementKeyInt": { attribute: schema.Int64Attribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.Int64Type"), }, "ElementKeyString": { attribute: schema.Int64Attribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.Int64Type"), }, "ElementKeyValue": { attribute: schema.Int64Attribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.Int64Type"), }, } diff --git a/provider/schema/list_attribute.go b/provider/schema/list_attribute.go index 1cfbbb6fc..b439efa62 100644 --- a/provider/schema/list_attribute.go +++ b/provider/schema/list_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -40,9 +41,9 @@ type ListAttribute struct { ElementType attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.ListType. When retrieving data, the types.ListValuable + // default basetypes.ListType. When retrieving data, the basetypes.ListValuable // associated with this custom type must be used in place of types.List. - CustomType types.ListTypable + CustomType basetypes.ListTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/list_nested_attribute.go b/provider/schema/list_nested_attribute.go index 000b380cc..fa8c577b4 100644 --- a/provider/schema/list_nested_attribute.go +++ b/provider/schema/list_nested_attribute.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -51,9 +52,9 @@ type ListNestedAttribute struct { // CustomType enables the use of a custom attribute type in place of the // default types.ListType of types.ObjectType. When retrieving data, the - // types.ListValuable associated with this custom type must be used in + // basetypes.ListValuable associated with this custom type must be used in // place of types.List. - CustomType types.ListTypable + CustomType basetypes.ListTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/list_nested_block.go b/provider/schema/list_nested_block.go index 29cf34465..29fc172a0 100644 --- a/provider/schema/list_nested_block.go +++ b/provider/schema/list_nested_block.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -55,9 +56,9 @@ type ListNestedBlock struct { // CustomType enables the use of a custom attribute type in place of the // default types.ListType of types.ObjectType. When retrieving data, the - // types.ListValuable associated with this custom type must be used in + // basetypes.ListValuable associated with this custom type must be used in // place of types.List. - CustomType types.ListTypable + CustomType basetypes.ListTypable // Description is used in various tooling, like the language server, to // give practitioners more information about what this attribute is, diff --git a/provider/schema/map_attribute.go b/provider/schema/map_attribute.go index 58cc56c04..13100e506 100644 --- a/provider/schema/map_attribute.go +++ b/provider/schema/map_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -43,9 +44,9 @@ type MapAttribute struct { ElementType attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.MapType. When retrieving data, the types.MapValuable + // default basetypes.MapType. When retrieving data, the basetypes.MapValuable // associated with this custom type must be used in place of types.Map. - CustomType types.MapTypable + CustomType basetypes.MapTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/map_nested_attribute.go b/provider/schema/map_nested_attribute.go index 9cf89b2d6..196c2e1ab 100644 --- a/provider/schema/map_nested_attribute.go +++ b/provider/schema/map_nested_attribute.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) // Ensure the implementation satisifies the desired interfaces. @@ -52,9 +53,9 @@ type MapNestedAttribute struct { // CustomType enables the use of a custom attribute type in place of the // default types.MapType of types.ObjectType. When retrieving data, the - // types.MapValuable associated with this custom type must be used in + // basetypes.MapValuable associated with this custom type must be used in // place of types.Map. - CustomType types.MapTypable + CustomType basetypes.MapTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/nested_attribute_object.go b/provider/schema/nested_attribute_object.go index a0b64e637..ae41a1873 100644 --- a/provider/schema/nested_attribute_object.go +++ b/provider/schema/nested_attribute_object.go @@ -4,7 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -27,9 +27,9 @@ type NestedAttributeObject struct { Attributes map[string]Attribute // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Validators define value validation functionality for the attribute. All // elements of the slice of AttributeValidator are run, regardless of any @@ -70,7 +70,7 @@ func (o NestedAttributeObject) ObjectValidators() []validator.Object { } // Type returns the framework type of the NestedAttributeObject. -func (o NestedAttributeObject) Type() types.ObjectTypable { +func (o NestedAttributeObject) Type() basetypes.ObjectTypable { if o.CustomType != nil { return o.CustomType } diff --git a/provider/schema/nested_block_object.go b/provider/schema/nested_block_object.go index 1885f3694..ea0cf61d6 100644 --- a/provider/schema/nested_block_object.go +++ b/provider/schema/nested_block_object.go @@ -4,7 +4,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -34,9 +34,9 @@ type NestedBlockObject struct { Blocks map[string]Block // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Validators define value validation functionality for the attribute. All // elements of the slice of AttributeValidator are run, regardless of any @@ -82,7 +82,7 @@ func (o NestedBlockObject) ObjectValidators() []validator.Object { } // Type returns the framework type of the NestedBlockObject. -func (o NestedBlockObject) Type() types.ObjectTypable { +func (o NestedBlockObject) Type() basetypes.ObjectTypable { if o.CustomType != nil { return o.CustomType } diff --git a/provider/schema/number_attribute.go b/provider/schema/number_attribute.go index 6c18a11b6..7281519e1 100644 --- a/provider/schema/number_attribute.go +++ b/provider/schema/number_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -33,9 +34,9 @@ var ( // .example_attribute type NumberAttribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.NumberType. When retrieving data, the types.NumberValuable + // default basetypes.NumberType. When retrieving data, the basetypes.NumberValuable // associated with this custom type must be used in place of types.Number. - CustomType types.NumberTypable + CustomType basetypes.NumberTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/number_attribute_test.go b/provider/schema/number_attribute_test.go index 18a838181..860ed4686 100644 --- a/provider/schema/number_attribute_test.go +++ b/provider/schema/number_attribute_test.go @@ -29,25 +29,25 @@ func TestNumberAttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.NumberAttribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.NumberType"), }, "ElementKeyInt": { attribute: schema.NumberAttribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.NumberType"), }, "ElementKeyString": { attribute: schema.NumberAttribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.NumberType"), }, "ElementKeyValue": { attribute: schema.NumberAttribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.NumberType"), }, } diff --git a/provider/schema/object_attribute.go b/provider/schema/object_attribute.go index d1b0315dd..76ad803a8 100644 --- a/provider/schema/object_attribute.go +++ b/provider/schema/object_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -42,9 +43,9 @@ type ObjectAttribute struct { AttributeTypes map[string]attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/set_attribute.go b/provider/schema/set_attribute.go index 1186976d8..3478eafc4 100644 --- a/provider/schema/set_attribute.go +++ b/provider/schema/set_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -38,9 +39,9 @@ type SetAttribute struct { ElementType attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.SetType. When retrieving data, the types.SetValuable + // default basetypes.SetType. When retrieving data, the basetypes.SetValuable // associated with this custom type must be used in place of types.Set. - CustomType types.SetTypable + CustomType basetypes.SetTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/set_nested_attribute.go b/provider/schema/set_nested_attribute.go index 74824a8b8..d04b6f838 100644 --- a/provider/schema/set_nested_attribute.go +++ b/provider/schema/set_nested_attribute.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) // Ensure the implementation satisifies the desired interfaces. @@ -47,9 +48,9 @@ type SetNestedAttribute struct { // CustomType enables the use of a custom attribute type in place of the // default types.SetType of types.ObjectType. When retrieving data, the - // types.SetValuable associated with this custom type must be used in + // basetypes.SetValuable associated with this custom type must be used in // place of types.Set. - CustomType types.SetTypable + CustomType basetypes.SetTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/set_nested_block.go b/provider/schema/set_nested_block.go index a21310abe..87d453f66 100644 --- a/provider/schema/set_nested_block.go +++ b/provider/schema/set_nested_block.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -55,9 +56,9 @@ type SetNestedBlock struct { // CustomType enables the use of a custom attribute type in place of the // default types.SetType of types.ObjectType. When retrieving data, the - // types.SetValuable associated with this custom type must be used in + // basetypes.SetValuable associated with this custom type must be used in // place of types.Set. - CustomType types.SetTypable + CustomType basetypes.SetTypable // Description is used in various tooling, like the language server, to // give practitioners more information about what this attribute is, diff --git a/provider/schema/single_nested_attribute.go b/provider/schema/single_nested_attribute.go index 020705ab4..de92fb990 100644 --- a/provider/schema/single_nested_attribute.go +++ b/provider/schema/single_nested_attribute.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) // Ensure the implementation satisifies the desired interfaces. @@ -46,9 +47,9 @@ type SingleNestedAttribute struct { Attributes map[string]Attribute // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/single_nested_block.go b/provider/schema/single_nested_block.go index 63a2b72ce..3f082be2e 100644 --- a/provider/schema/single_nested_block.go +++ b/provider/schema/single_nested_block.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -56,9 +57,9 @@ type SingleNestedBlock struct { Blocks map[string]Block // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Description is used in various tooling, like the language server, to // give practitioners more information about what this attribute is, diff --git a/provider/schema/string_attribute.go b/provider/schema/string_attribute.go index 6f284eebe..eef7da7e9 100644 --- a/provider/schema/string_attribute.go +++ b/provider/schema/string_attribute.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -29,9 +30,9 @@ var ( // .example_attribute type StringAttribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.StringType. When retrieving data, the types.StringValuable + // default basetypes.StringType. When retrieving data, the basetypes.StringValuable // associated with this custom type must be used in place of types.String. - CustomType types.StringTypable + CustomType basetypes.StringTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/provider/schema/string_attribute_test.go b/provider/schema/string_attribute_test.go index 0f4acb09d..43bc421c7 100644 --- a/provider/schema/string_attribute_test.go +++ b/provider/schema/string_attribute_test.go @@ -29,25 +29,25 @@ func TestStringAttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.StringAttribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.StringType"), }, "ElementKeyInt": { attribute: schema.StringAttribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.StringType"), }, "ElementKeyString": { attribute: schema.StringAttribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.StringType"), }, "ElementKeyValue": { attribute: schema.StringAttribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.StringType"), }, } diff --git a/resource/schema/bool_attribute.go b/resource/schema/bool_attribute.go index 32532f4ba..d99233e86 100644 --- a/resource/schema/bool_attribute.go +++ b/resource/schema/bool_attribute.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -31,9 +32,9 @@ var ( // .example_attribute type BoolAttribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.BoolType. When retrieving data, the types.BoolValuable + // default basetypes.BoolType. When retrieving data, the basetypes.BoolValuable // associated with this custom type must be used in place of types.Bool. - CustomType types.BoolTypable + CustomType basetypes.BoolTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/bool_attribute_test.go b/resource/schema/bool_attribute_test.go index c0e77c718..6e5773b0b 100644 --- a/resource/schema/bool_attribute_test.go +++ b/resource/schema/bool_attribute_test.go @@ -30,25 +30,25 @@ func TestBoolAttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.BoolAttribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.BoolType"), }, "ElementKeyInt": { attribute: schema.BoolAttribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.BoolType"), }, "ElementKeyString": { attribute: schema.BoolAttribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.BoolType"), }, "ElementKeyValue": { attribute: schema.BoolAttribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.BoolType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.BoolType"), }, } diff --git a/resource/schema/float64_attribute.go b/resource/schema/float64_attribute.go index 3f3692e37..0ab00417b 100644 --- a/resource/schema/float64_attribute.go +++ b/resource/schema/float64_attribute.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -34,9 +35,9 @@ var ( // .example_attribute type Float64Attribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.Float64Type. When retrieving data, the types.Float64Valuable + // default basetypes.Float64Type. When retrieving data, the basetypes.Float64Valuable // associated with this custom type must be used in place of types.Float64. - CustomType types.Float64Typable + CustomType basetypes.Float64Typable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/float64_attribute_test.go b/resource/schema/float64_attribute_test.go index c4beb7c4e..d7c56da2c 100644 --- a/resource/schema/float64_attribute_test.go +++ b/resource/schema/float64_attribute_test.go @@ -29,25 +29,25 @@ func TestFloat64AttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.Float64Attribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.Float64Type"), }, "ElementKeyInt": { attribute: schema.Float64Attribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.Float64Type"), }, "ElementKeyString": { attribute: schema.Float64Attribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.Float64Type"), }, "ElementKeyValue": { attribute: schema.Float64Attribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.Float64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.Float64Type"), }, } diff --git a/resource/schema/int64_attribute.go b/resource/schema/int64_attribute.go index 0efcf0762..0dd4b93e0 100644 --- a/resource/schema/int64_attribute.go +++ b/resource/schema/int64_attribute.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -34,9 +35,9 @@ var ( // .example_attribute type Int64Attribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.Int64Type. When retrieving data, the types.Int64Valuable + // default basetypes.Int64Type. When retrieving data, the basetypes.Int64Valuable // associated with this custom type must be used in place of types.Int64. - CustomType types.Int64Typable + CustomType basetypes.Int64Typable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/int64_attribute_test.go b/resource/schema/int64_attribute_test.go index 0968a371f..4aee32509 100644 --- a/resource/schema/int64_attribute_test.go +++ b/resource/schema/int64_attribute_test.go @@ -29,25 +29,25 @@ func TestInt64AttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.Int64Attribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.Int64Type"), }, "ElementKeyInt": { attribute: schema.Int64Attribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.Int64Type"), }, "ElementKeyString": { attribute: schema.Int64Attribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.Int64Type"), }, "ElementKeyValue": { attribute: schema.Int64Attribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.Int64Type"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.Int64Type"), }, } diff --git a/resource/schema/list_attribute.go b/resource/schema/list_attribute.go index e0333a402..f65535174 100644 --- a/resource/schema/list_attribute.go +++ b/resource/schema/list_attribute.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -42,9 +43,9 @@ type ListAttribute struct { ElementType attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.ListType. When retrieving data, the types.ListValuable + // default basetypes.ListType. When retrieving data, the basetypes.ListValuable // associated with this custom type must be used in place of types.List. - CustomType types.ListTypable + CustomType basetypes.ListTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/list_nested_attribute.go b/resource/schema/list_nested_attribute.go index 978dd952d..fdd6a3273 100644 --- a/resource/schema/list_nested_attribute.go +++ b/resource/schema/list_nested_attribute.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -53,9 +54,9 @@ type ListNestedAttribute struct { // CustomType enables the use of a custom attribute type in place of the // default types.ListType of types.ObjectType. When retrieving data, the - // types.ListValuable associated with this custom type must be used in + // basetypes.ListValuable associated with this custom type must be used in // place of types.List. - CustomType types.ListTypable + CustomType basetypes.ListTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/list_nested_block.go b/resource/schema/list_nested_block.go index 14e7e1c81..16aef6ec1 100644 --- a/resource/schema/list_nested_block.go +++ b/resource/schema/list_nested_block.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -57,9 +58,9 @@ type ListNestedBlock struct { // CustomType enables the use of a custom attribute type in place of the // default types.ListType of types.ObjectType. When retrieving data, the - // types.ListValuable associated with this custom type must be used in + // basetypes.ListValuable associated with this custom type must be used in // place of types.List. - CustomType types.ListTypable + CustomType basetypes.ListTypable // Description is used in various tooling, like the language server, to // give practitioners more information about what this attribute is, diff --git a/resource/schema/map_attribute.go b/resource/schema/map_attribute.go index c99ee4c3c..d9b8ee294 100644 --- a/resource/schema/map_attribute.go +++ b/resource/schema/map_attribute.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -45,9 +46,9 @@ type MapAttribute struct { ElementType attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.MapType. When retrieving data, the types.MapValuable + // default basetypes.MapType. When retrieving data, the basetypes.MapValuable // associated with this custom type must be used in place of types.Map. - CustomType types.MapTypable + CustomType basetypes.MapTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/map_nested_attribute.go b/resource/schema/map_nested_attribute.go index 3b937329e..e46197d1c 100644 --- a/resource/schema/map_nested_attribute.go +++ b/resource/schema/map_nested_attribute.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) // Ensure the implementation satisifies the desired interfaces. @@ -54,9 +55,9 @@ type MapNestedAttribute struct { // CustomType enables the use of a custom attribute type in place of the // default types.MapType of types.ObjectType. When retrieving data, the - // types.MapValuable associated with this custom type must be used in + // basetypes.MapValuable associated with this custom type must be used in // place of types.Map. - CustomType types.MapTypable + CustomType basetypes.MapTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/nested_attribute_object.go b/resource/schema/nested_attribute_object.go index 6fe14036a..e49d01988 100644 --- a/resource/schema/nested_attribute_object.go +++ b/resource/schema/nested_attribute_object.go @@ -5,7 +5,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -31,9 +31,9 @@ type NestedAttributeObject struct { Attributes map[string]Attribute // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Validators define value validation functionality for the attribute. All // elements of the slice of AttributeValidator are run, regardless of any @@ -96,7 +96,7 @@ func (o NestedAttributeObject) ObjectValidators() []validator.Object { } // Type returns the framework type of the NestedAttributeObject. -func (o NestedAttributeObject) Type() types.ObjectTypable { +func (o NestedAttributeObject) Type() basetypes.ObjectTypable { if o.CustomType != nil { return o.CustomType } diff --git a/resource/schema/nested_block_object.go b/resource/schema/nested_block_object.go index 11d09ee6f..4f2e449b2 100644 --- a/resource/schema/nested_block_object.go +++ b/resource/schema/nested_block_object.go @@ -5,7 +5,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema" "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -38,9 +38,9 @@ type NestedBlockObject struct { Blocks map[string]Block // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Validators define value validation functionality for the attribute. All // elements of the slice of AttributeValidator are run, regardless of any @@ -108,7 +108,7 @@ func (o NestedBlockObject) ObjectValidators() []validator.Object { } // Type returns the framework type of the NestedBlockObject. -func (o NestedBlockObject) Type() types.ObjectTypable { +func (o NestedBlockObject) Type() basetypes.ObjectTypable { if o.CustomType != nil { return o.CustomType } diff --git a/resource/schema/number_attribute.go b/resource/schema/number_attribute.go index 4e720224d..ae55d7e1c 100644 --- a/resource/schema/number_attribute.go +++ b/resource/schema/number_attribute.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -35,9 +36,9 @@ var ( // .example_attribute type NumberAttribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.NumberType. When retrieving data, the types.NumberValuable + // default basetypes.NumberType. When retrieving data, the basetypes.NumberValuable // associated with this custom type must be used in place of types.Number. - CustomType types.NumberTypable + CustomType basetypes.NumberTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/number_attribute_test.go b/resource/schema/number_attribute_test.go index c4ad986af..8a777b777 100644 --- a/resource/schema/number_attribute_test.go +++ b/resource/schema/number_attribute_test.go @@ -30,25 +30,25 @@ func TestNumberAttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.NumberAttribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.NumberType"), }, "ElementKeyInt": { attribute: schema.NumberAttribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.NumberType"), }, "ElementKeyString": { attribute: schema.NumberAttribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.NumberType"), }, "ElementKeyValue": { attribute: schema.NumberAttribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.NumberType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.NumberType"), }, } diff --git a/resource/schema/object_attribute.go b/resource/schema/object_attribute.go index cf3e8409c..9740dd08e 100644 --- a/resource/schema/object_attribute.go +++ b/resource/schema/object_attribute.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -44,9 +45,9 @@ type ObjectAttribute struct { AttributeTypes map[string]attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/planmodifier/doc.go b/resource/schema/planmodifier/doc.go index 97ec55235..182964a46 100644 --- a/resource/schema/planmodifier/doc.go +++ b/resource/schema/planmodifier/doc.go @@ -11,7 +11,7 @@ // // The framework has to choose between plan modifier developers handling a // concrete framework value type, such as types.Bool, or the framework -// interface for custom value types, such as types.BoolValuable. +// interface for custom value basetypes. such as basetypes.BoolValuable. // // In the framework type model, the developer can immediately use the value. // If the value was associated with a custom type and using the custom value diff --git a/resource/schema/set_attribute.go b/resource/schema/set_attribute.go index 820e32011..2a73823e7 100644 --- a/resource/schema/set_attribute.go +++ b/resource/schema/set_attribute.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -40,9 +41,9 @@ type SetAttribute struct { ElementType attr.Type // CustomType enables the use of a custom attribute type in place of the - // default types.SetType. When retrieving data, the types.SetValuable + // default basetypes.SetType. When retrieving data, the basetypes.SetValuable // associated with this custom type must be used in place of types.Set. - CustomType types.SetTypable + CustomType basetypes.SetTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/set_nested_attribute.go b/resource/schema/set_nested_attribute.go index 6496a3b15..17a6a65b2 100644 --- a/resource/schema/set_nested_attribute.go +++ b/resource/schema/set_nested_attribute.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) // Ensure the implementation satisifies the desired interfaces. @@ -49,9 +50,9 @@ type SetNestedAttribute struct { // CustomType enables the use of a custom attribute type in place of the // default types.SetType of types.ObjectType. When retrieving data, the - // types.SetValuable associated with this custom type must be used in + // basetypes.SetValuable associated with this custom type must be used in // place of types.Set. - CustomType types.SetTypable + CustomType basetypes.SetTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/set_nested_block.go b/resource/schema/set_nested_block.go index b0da55236..3b99a73c2 100644 --- a/resource/schema/set_nested_block.go +++ b/resource/schema/set_nested_block.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -57,9 +58,9 @@ type SetNestedBlock struct { // CustomType enables the use of a custom attribute type in place of the // default types.SetType of types.ObjectType. When retrieving data, the - // types.SetValuable associated with this custom type must be used in + // basetypes.SetValuable associated with this custom type must be used in // place of types.Set. - CustomType types.SetTypable + CustomType basetypes.SetTypable // Description is used in various tooling, like the language server, to // give practitioners more information about what this attribute is, diff --git a/resource/schema/single_nested_attribute.go b/resource/schema/single_nested_attribute.go index 44eb906f2..c49903205 100644 --- a/resource/schema/single_nested_attribute.go +++ b/resource/schema/single_nested_attribute.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" ) // Ensure the implementation satisifies the desired interfaces. @@ -48,9 +49,9 @@ type SingleNestedAttribute struct { Attributes map[string]Attribute // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/single_nested_block.go b/resource/schema/single_nested_block.go index 17c3d1a89..1b62c9f06 100644 --- a/resource/schema/single_nested_block.go +++ b/resource/schema/single_nested_block.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -58,9 +59,9 @@ type SingleNestedBlock struct { Blocks map[string]Block // CustomType enables the use of a custom attribute type in place of the - // default types.ObjectType. When retrieving data, the types.ObjectValuable + // default basetypes.ObjectType. When retrieving data, the basetypes.ObjectValuable // associated with this custom type must be used in place of types.Object. - CustomType types.ObjectTypable + CustomType basetypes.ObjectTypable // Description is used in various tooling, like the language server, to // give practitioners more information about what this attribute is, diff --git a/resource/schema/string_attribute.go b/resource/schema/string_attribute.go index bd59176c0..2d20b63fa 100644 --- a/resource/schema/string_attribute.go +++ b/resource/schema/string_attribute.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -31,9 +32,9 @@ var ( // .example_attribute type StringAttribute struct { // CustomType enables the use of a custom attribute type in place of the - // default types.StringType. When retrieving data, the types.StringValuable + // default basetypes.StringType. When retrieving data, the basetypes.StringValuable // associated with this custom type must be used in place of types.String. - CustomType types.StringTypable + CustomType basetypes.StringTypable // Required indicates whether the practitioner must enter a value for // this attribute or not. Required and Optional cannot both be true, diff --git a/resource/schema/string_attribute_test.go b/resource/schema/string_attribute_test.go index d1a9115b6..35f5c81c5 100644 --- a/resource/schema/string_attribute_test.go +++ b/resource/schema/string_attribute_test.go @@ -30,25 +30,25 @@ func TestStringAttributeApplyTerraform5AttributePathStep(t *testing.T) { attribute: schema.StringAttribute{}, step: tftypes.AttributeName("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.StringType"), }, "ElementKeyInt": { attribute: schema.StringAttribute{}, step: tftypes.ElementKeyInt(1), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.StringType"), }, "ElementKeyString": { attribute: schema.StringAttribute{}, step: tftypes.ElementKeyString("test"), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.StringType"), }, "ElementKeyValue": { attribute: schema.StringAttribute{}, step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), expected: nil, - expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to types.StringType"), + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.StringType"), }, } diff --git a/schema/validator/doc.go b/schema/validator/doc.go index ad33ed716..c90e9901d 100644 --- a/schema/validator/doc.go +++ b/schema/validator/doc.go @@ -10,7 +10,7 @@ // // The framework has to choose between validator developers handling a concrete // framework value type, such as types.Bool, or the framework interface for -// custom value types, such as types.BoolValuable. +// custom value basetypes. such as basetypes.BoolValuable. // // In the framework type model, the developer can immediately use the value. // If the value was associated with a custom type and using the custom value diff --git a/tfsdk/convert_test.go b/tfsdk/convert_test.go index de7593d76..1bada37e6 100644 --- a/tfsdk/convert_test.go +++ b/tfsdk/convert_test.go @@ -43,7 +43,7 @@ func TestConvert(t *testing.T) { typ: types.NumberType, expectedDiags: diag.Diagnostics{diag.NewErrorDiagnostic( "Error converting value", - "An unexpected error was encountered converting a types.String to a types.NumberType. This is always a problem with the provider. Please tell the provider developers that types.NumberType returned the following error when calling ValueFromTerraform: can't unmarshal tftypes.String into *big.Float, expected *big.Float", + "An unexpected error was encountered converting a basetypes.StringValue to a basetypes.NumberType. This is always a problem with the provider. Please tell the provider developers that basetypes.NumberType returned the following error when calling ValueFromTerraform: can't unmarshal tftypes.String into *big.Float, expected *big.Float", )}, }, } diff --git a/tfsdk/nested_attribute_object.go b/tfsdk/nested_attribute_object.go index ff22671bf..60dadfea5 100644 --- a/tfsdk/nested_attribute_object.go +++ b/tfsdk/nested_attribute_object.go @@ -2,7 +2,7 @@ package tfsdk import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -39,6 +39,6 @@ func (o nestedAttributeObject) GetAttributes() fwschema.UnderlyingAttributes { } // Type returns the framework type of the nestedAttributeObject. -func (o nestedAttributeObject) Type() types.ObjectTypable { +func (o nestedAttributeObject) Type() basetypes.ObjectTypable { return fwschema.NestedAttributeObjectType(o) } diff --git a/tfsdk/nested_block_object.go b/tfsdk/nested_block_object.go index 4af45c46b..b7e6e763f 100644 --- a/tfsdk/nested_block_object.go +++ b/tfsdk/nested_block_object.go @@ -2,7 +2,7 @@ package tfsdk import ( "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" - "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" "github.com/hashicorp/terraform-plugin-go/tftypes" ) @@ -55,6 +55,6 @@ func (o nestedBlockObject) GetBlocks() map[string]fwschema.Block { } // Type returns the framework type of the nestedBlockObject. -func (o nestedBlockObject) Type() types.ObjectTypable { +func (o nestedBlockObject) Type() basetypes.ObjectTypable { return fwschema.NestedBlockObjectType(o) } diff --git a/tfsdk/schema_test.go b/tfsdk/schema_test.go index d7181a536..09f5fc784 100644 --- a/tfsdk/schema_test.go +++ b/tfsdk/schema_test.go @@ -1392,7 +1392,7 @@ func TestSchemaAttributeAtPath(t *testing.T) { "When attempting to get the framework attribute associated with a schema path, an unexpected error was returned. "+ "This is always an issue with the provider. Please report this to the provider developers.\n\n"+ "Path: test[0]\n"+ - "Original Error: ElementKeyInt(0) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyInt to types.StringType", + "Original Error: ElementKeyInt(0) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.StringType", ), }, }, @@ -1446,7 +1446,7 @@ func TestSchemaAttributeAtPath(t *testing.T) { "When attempting to get the framework attribute associated with a schema path, an unexpected error was returned. "+ "This is always an issue with the provider. Please report this to the provider developers.\n\n"+ "Path: test[\"element\"]\n"+ - "Original Error: ElementKeyString(\"element\") still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyString to types.StringType", + "Original Error: ElementKeyString(\"element\") still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.StringType", ), }, }, @@ -1500,7 +1500,7 @@ func TestSchemaAttributeAtPath(t *testing.T) { "When attempting to get the framework attribute associated with a schema path, an unexpected error was returned. "+ "This is always an issue with the provider. Please report this to the provider developers.\n\n"+ "Path: test[Value(\"element\")]\n"+ - "Original Error: ElementKeyValue(tftypes.String<\"element\">) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyValue to types.StringType", + "Original Error: ElementKeyValue(tftypes.String<\"element\">) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.StringType", ), }, }, @@ -2747,7 +2747,7 @@ func TestSchemaAttributeAtTerraformPath(t *testing.T) { }, path: tftypes.NewAttributePath().WithAttributeName("test").WithElementKeyInt(0), expected: Attribute{}, - expectedErr: "ElementKeyInt(0) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyInt to types.StringType", + expectedErr: "ElementKeyInt(0) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.StringType", }, "WithAttributeName-WithElementKeyInt-valid-parent": { schema: Schema{ @@ -2783,7 +2783,7 @@ func TestSchemaAttributeAtTerraformPath(t *testing.T) { }, path: tftypes.NewAttributePath().WithAttributeName("test").WithElementKeyString("element"), expected: Attribute{}, - expectedErr: "ElementKeyString(\"element\") still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyString to types.StringType", + expectedErr: "ElementKeyString(\"element\") still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.StringType", }, "WithAttributeName-WithElementKeyString-valid-parent": { schema: Schema{ @@ -2819,7 +2819,7 @@ func TestSchemaAttributeAtTerraformPath(t *testing.T) { }, path: tftypes.NewAttributePath().WithAttributeName("test").WithElementKeyValue(tftypes.NewValue(tftypes.String, "element")), expected: Attribute{}, - expectedErr: "ElementKeyValue(tftypes.String<\"element\">) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyValue to types.StringType", + expectedErr: "ElementKeyValue(tftypes.String<\"element\">) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.StringType", }, "WithAttributeName-WithElementKeyValue-valid-parent": { schema: Schema{ diff --git a/types/bool.go b/types/basetypes/bool.go similarity index 60% rename from types/bool.go rename to types/basetypes/bool.go index 2b4bd5236..d0e3a2910 100644 --- a/types/bool.go +++ b/types/basetypes/bool.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -11,7 +11,7 @@ import ( ) var ( - _ BoolValuable = Bool{} + _ BoolValuable = BoolValue{} ) // BoolValuable extends attr.Value for boolean value types. @@ -20,60 +20,36 @@ type BoolValuable interface { attr.Value // ToBoolValue should convert the value type to a Bool. - ToBoolValue(ctx context.Context) (Bool, diag.Diagnostics) + ToBoolValue(ctx context.Context) (BoolValue, diag.Diagnostics) } -// BoolNull creates a Bool with a null value. Determine whether the value is +// NewBoolNull creates a Bool with a null value. Determine whether the value is // null via the Bool type IsNull method. -// -// Setting the deprecated Bool type Null, Unknown, or Value fields after -// creating a Bool with this function has no effect. -func BoolNull() Bool { - return Bool{ +func NewBoolNull() BoolValue { + return BoolValue{ state: attr.ValueStateNull, } } -// BoolUnknown creates a Bool with an unknown value. Determine whether the +// NewBoolUnknown creates a Bool with an unknown value. Determine whether the // value is unknown via the Bool type IsUnknown method. -// -// Setting the deprecated Bool type Null, Unknown, or Value fields after -// creating a Bool with this function has no effect. -func BoolUnknown() Bool { - return Bool{ +func NewBoolUnknown() BoolValue { + return BoolValue{ state: attr.ValueStateUnknown, } } -// BoolValue creates a Bool with a known value. Access the value via the Bool +// NewBoolValue creates a Bool with a known value. Access the value via the Bool // type ValueBool method. -// -// Setting the deprecated Bool type Null, Unknown, or Value fields after -// creating a Bool with this function has no effect. -func BoolValue(value bool) Bool { - return Bool{ +func NewBoolValue(value bool) BoolValue { + return BoolValue{ state: attr.ValueStateKnown, value: value, } } -func boolValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { - if in.IsNull() { - return BoolNull(), nil - } - if !in.IsKnown() { - return BoolUnknown(), nil - } - var b bool - err := in.As(&b) - if err != nil { - return nil, err - } - return BoolValue(b), nil -} - -// Bool represents a boolean value. -type Bool struct { +// BoolValue represents a boolean value. +type BoolValue struct { // state represents whether the value is null, unknown, or known. The // zero-value is null. state attr.ValueState @@ -83,12 +59,12 @@ type Bool struct { } // Type returns a BoolType. -func (b Bool) Type(_ context.Context) attr.Type { - return BoolType +func (b BoolValue) Type(_ context.Context) attr.Type { + return BoolType{} } // ToTerraformValue returns the data contained in the Bool as a tftypes.Value. -func (b Bool) ToTerraformValue(_ context.Context) (tftypes.Value, error) { +func (b BoolValue) ToTerraformValue(_ context.Context) (tftypes.Value, error) { switch b.state { case attr.ValueStateKnown: if err := tftypes.ValidateValue(tftypes.Bool, b.value); err != nil { @@ -106,8 +82,8 @@ func (b Bool) ToTerraformValue(_ context.Context) (tftypes.Value, error) { } // Equal returns true if `other` is a *Bool and has the same value as `b`. -func (b Bool) Equal(other attr.Value) bool { - o, ok := other.(Bool) +func (b BoolValue) Equal(other attr.Value) bool { + o, ok := other.(BoolValue) if !ok { return false @@ -125,19 +101,19 @@ func (b Bool) Equal(other attr.Value) bool { } // IsNull returns true if the Bool represents a null value. -func (b Bool) IsNull() bool { +func (b BoolValue) IsNull() bool { return b.state == attr.ValueStateNull } // IsUnknown returns true if the Bool represents a currently unknown value. -func (b Bool) IsUnknown() bool { +func (b BoolValue) IsUnknown() bool { return b.state == attr.ValueStateUnknown } // String returns a human-readable representation of the Bool value. // The string returned here is not protected by any compatibility guarantees, // and is intended for logging and error reporting. -func (b Bool) String() string { +func (b BoolValue) String() string { if b.IsUnknown() { return attr.UnknownValueString } @@ -151,11 +127,11 @@ func (b Bool) String() string { // ValueBool returns the known bool value. If Bool is null or unknown, returns // false. -func (b Bool) ValueBool() bool { +func (b BoolValue) ValueBool() bool { return b.value } // ToBoolValue returns Bool. -func (b Bool) ToBoolValue(context.Context) (Bool, diag.Diagnostics) { +func (b BoolValue) ToBoolValue(context.Context) (BoolValue, diag.Diagnostics) { return b, nil } diff --git a/types/bool_test.go b/types/basetypes/bool_test.go similarity index 71% rename from types/bool_test.go rename to types/basetypes/bool_test.go index 66c208aa0..6c1accf91 100644 --- a/types/bool_test.go +++ b/types/basetypes/bool_test.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -9,13 +9,9 @@ import ( "github.com/hashicorp/terraform-plugin-go/tftypes" ) -func TestBoolValueFromTerraform(t *testing.T) { +func TestBoolTypeValueFromTerraform(t *testing.T) { t.Parallel() - testBoolValueFromTerraform(t, true) -} - -func testBoolValueFromTerraform(t *testing.T, direct bool) { type testCase struct { input tftypes.Value expectation attr.Value @@ -24,19 +20,19 @@ func testBoolValueFromTerraform(t *testing.T, direct bool) { tests := map[string]testCase{ "true": { input: tftypes.NewValue(tftypes.Bool, true), - expectation: BoolValue(true), + expectation: NewBoolValue(true), }, "false": { input: tftypes.NewValue(tftypes.Bool, false), - expectation: BoolValue(false), + expectation: NewBoolValue(false), }, "unknown": { input: tftypes.NewValue(tftypes.Bool, tftypes.UnknownValue), - expectation: BoolUnknown(), + expectation: NewBoolUnknown(), }, "null": { input: tftypes.NewValue(tftypes.Bool, nil), - expectation: BoolNull(), + expectation: NewBoolNull(), }, "wrongType": { input: tftypes.NewValue(tftypes.String, "oops"), @@ -49,11 +45,7 @@ func testBoolValueFromTerraform(t *testing.T, direct bool) { t.Parallel() ctx := context.Background() - f := BoolType.ValueFromTerraform - if direct { - f = boolValueFromTerraform - } - got, err := f(ctx, test.input) + got, err := BoolType{}.ValueFromTerraform(ctx, test.input) if err != nil { if test.expectedErr == "" { t.Errorf("Unexpected error: %s", err) @@ -84,28 +76,28 @@ func testBoolValueFromTerraform(t *testing.T, direct bool) { } } -func TestBoolToTerraformValue(t *testing.T) { +func TestBoolValueToTerraformValue(t *testing.T) { t.Parallel() type testCase struct { - input Bool + input BoolValue expectation interface{} } tests := map[string]testCase{ "known-true": { - input: BoolValue(true), + input: NewBoolValue(true), expectation: tftypes.NewValue(tftypes.Bool, true), }, "known-false": { - input: BoolValue(false), + input: NewBoolValue(false), expectation: tftypes.NewValue(tftypes.Bool, false), }, "unknown": { - input: BoolUnknown(), + input: NewBoolUnknown(), expectation: tftypes.NewValue(tftypes.Bool, tftypes.UnknownValue), }, "null": { - input: BoolNull(), + input: NewBoolNull(), expectation: tftypes.NewValue(tftypes.Bool, nil), }, } @@ -127,103 +119,103 @@ func TestBoolToTerraformValue(t *testing.T) { } } -func TestBoolEqual(t *testing.T) { +func TestBoolValueEqual(t *testing.T) { t.Parallel() type testCase struct { - input Bool + input BoolValue candidate attr.Value expectation bool } tests := map[string]testCase{ "known-true-nil": { - input: BoolValue(true), + input: NewBoolValue(true), candidate: nil, expectation: false, }, "known-true-wrongtype": { - input: BoolValue(true), - candidate: StringValue("true"), + input: NewBoolValue(true), + candidate: NewStringValue("true"), expectation: false, }, "known-true-known-false": { - input: BoolValue(true), - candidate: BoolValue(false), + input: NewBoolValue(true), + candidate: NewBoolValue(false), expectation: false, }, "known-true-known-true": { - input: BoolValue(true), - candidate: BoolValue(true), + input: NewBoolValue(true), + candidate: NewBoolValue(true), expectation: true, }, "known-true-null": { - input: BoolValue(true), - candidate: BoolNull(), + input: NewBoolValue(true), + candidate: NewBoolNull(), expectation: false, }, "known-true-unknown": { - input: BoolValue(true), - candidate: BoolUnknown(), + input: NewBoolValue(true), + candidate: NewBoolUnknown(), expectation: false, }, "known-false-nil": { - input: BoolValue(false), + input: NewBoolValue(false), candidate: nil, expectation: false, }, "known-false-wrongtype": { - input: BoolValue(false), - candidate: StringValue("false"), + input: NewBoolValue(false), + candidate: NewStringValue("false"), expectation: false, }, "known-false-known-false": { - input: BoolValue(false), - candidate: BoolValue(false), + input: NewBoolValue(false), + candidate: NewBoolValue(false), expectation: true, }, "known-false-known-true": { - input: BoolValue(false), - candidate: BoolValue(true), + input: NewBoolValue(false), + candidate: NewBoolValue(true), expectation: false, }, "known-false-null": { - input: BoolValue(false), - candidate: BoolNull(), + input: NewBoolValue(false), + candidate: NewBoolNull(), expectation: false, }, "known-false-unknown": { - input: BoolValue(false), - candidate: BoolUnknown(), + input: NewBoolValue(false), + candidate: NewBoolUnknown(), expectation: false, }, "null-nil": { - input: BoolNull(), + input: NewBoolNull(), candidate: nil, expectation: false, }, "null-wrongtype": { - input: BoolNull(), - candidate: StringValue("true"), + input: NewBoolNull(), + candidate: NewStringValue("true"), expectation: false, }, "null-known-false": { - input: BoolNull(), - candidate: BoolValue(false), + input: NewBoolNull(), + candidate: NewBoolValue(false), expectation: false, }, "null-known-true": { - input: BoolNull(), - candidate: BoolValue(true), + input: NewBoolNull(), + candidate: NewBoolValue(true), expectation: false, }, "null-null": { - input: BoolNull(), - candidate: BoolNull(), + input: NewBoolNull(), + candidate: NewBoolNull(), expectation: true, }, "null-unknown": { - input: BoolNull(), - candidate: BoolUnknown(), + input: NewBoolNull(), + candidate: NewBoolUnknown(), expectation: false, }, } @@ -240,23 +232,23 @@ func TestBoolEqual(t *testing.T) { } } -func TestBoolIsNull(t *testing.T) { +func TestBoolValueIsNull(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Bool + input BoolValue expected bool }{ "known": { - input: BoolValue(true), + input: NewBoolValue(true), expected: false, }, "null": { - input: BoolNull(), + input: NewBoolNull(), expected: true, }, "unknown": { - input: BoolUnknown(), + input: NewBoolUnknown(), expected: false, }, } @@ -276,23 +268,23 @@ func TestBoolIsNull(t *testing.T) { } } -func TestBoolIsUnknown(t *testing.T) { +func TestBoolValueIsUnknown(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Bool + input BoolValue expected bool }{ "known": { - input: BoolValue(true), + input: NewBoolValue(true), expected: false, }, "null": { - input: BoolNull(), + input: NewBoolNull(), expected: false, }, "unknown": { - input: BoolUnknown(), + input: NewBoolUnknown(), expected: true, }, } @@ -312,28 +304,28 @@ func TestBoolIsUnknown(t *testing.T) { } } -func TestBoolString(t *testing.T) { +func TestBoolValueString(t *testing.T) { t.Parallel() type testCase struct { - input Bool + input BoolValue expectation string } tests := map[string]testCase{ "known-true": { - input: BoolValue(true), + input: NewBoolValue(true), expectation: "true", }, "known-false": { - input: BoolValue(false), + input: NewBoolValue(false), expectation: "false", }, "null": { - input: BoolNull(), + input: NewBoolNull(), expectation: "", }, "unknown": { - input: BoolUnknown(), + input: NewBoolUnknown(), expectation: "", }, } @@ -351,27 +343,27 @@ func TestBoolString(t *testing.T) { } } -func TestBoolValueBool(t *testing.T) { +func TestBoolValueValueBool(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Bool + input BoolValue expected bool }{ "known-false": { - input: BoolValue(false), + input: NewBoolValue(false), expected: false, }, "known-true": { - input: BoolValue(true), + input: NewBoolValue(true), expected: true, }, "null": { - input: BoolNull(), + input: NewBoolNull(), expected: false, }, "unknown": { - input: BoolUnknown(), + input: NewBoolUnknown(), expected: false, }, } diff --git a/types/basetypes/bool_type.go b/types/basetypes/bool_type.go new file mode 100644 index 000000000..5891ce9a2 --- /dev/null +++ b/types/basetypes/bool_type.go @@ -0,0 +1,83 @@ +package basetypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// BoolTypable extends attr.Type for bool types. +// Implement this interface to create a custom BoolType type. +type BoolTypable interface { + attr.Type + + // ValueFromBool should convert the Bool to a BoolValuable type. + ValueFromBool(context.Context, BoolValue) (BoolValuable, diag.Diagnostics) +} + +var _ BoolTypable = BoolType{} + +// BoolType is the base framework type for a boolean. BoolValue is the +// associated value type. +type BoolType struct{} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// type. +func (t BoolType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// Equal returns true if the given type is equivalent. +func (t BoolType) Equal(o attr.Type) bool { + _, ok := o.(BoolType) + + return ok +} + +// String returns a human readable string of the type name. +func (t BoolType) String() string { + return "basetypes.BoolType" +} + +// TerraformType returns the tftypes.Type that should be used to represent this +// framework type. +func (t BoolType) TerraformType(_ context.Context) tftypes.Type { + return tftypes.Bool +} + +// ValueFromBool returns a BoolValuable type given a BoolValue. +func (t BoolType) ValueFromBool(_ context.Context, v BoolValue) (BoolValuable, diag.Diagnostics) { + return v, nil +} + +// ValueFromTerraform returns a Value given a tftypes.Value. This is meant to +// convert the tftypes.Value into a more convenient Go type for the provider to +// consume the data with. +func (t BoolType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if !in.IsKnown() { + return NewBoolUnknown(), nil + } + + if in.IsNull() { + return NewBoolNull(), nil + } + + var v bool + + err := in.As(&v) + + if err != nil { + return nil, err + } + + return NewBoolValue(v), nil +} + +// ValueType returns the Value type. +func (t BoolType) ValueType(_ context.Context) attr.Value { + // This Value does not need to be valid. + return BoolValue{} +} diff --git a/types/basetypes/doc.go b/types/basetypes/doc.go new file mode 100644 index 000000000..25ce0e1e1 --- /dev/null +++ b/types/basetypes/doc.go @@ -0,0 +1,4 @@ +// Package basetypes contains the implementations for framework-defined data +// types and values, such as boolean, floating point, integer, list, map, +// object, set, and string. Embed these implementations to create custom types. +package basetypes diff --git a/types/float64.go b/types/basetypes/float64.go similarity index 52% rename from types/float64.go rename to types/basetypes/float64.go index cb5993a7a..d59b9cf99 100644 --- a/types/float64.go +++ b/types/basetypes/float64.go @@ -1,19 +1,17 @@ -package types +package basetypes import ( "context" "fmt" - "math/big" "github.com/hashicorp/terraform-plugin-go/tftypes" "github.com/hashicorp/terraform-plugin-framework/attr" "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" ) var ( - _ Float64Valuable = Float64{} + _ Float64Valuable = Float64Value{} ) // Float64Valuable extends attr.Value for float64 value types. @@ -22,16 +20,13 @@ type Float64Valuable interface { attr.Value // ToFloat64Value should convert the value type to a Float64. - ToFloat64Value(ctx context.Context) (Float64, diag.Diagnostics) + ToFloat64Value(ctx context.Context) (Float64Value, diag.Diagnostics) } // Float64Null creates a Float64 with a null value. Determine whether the value is // null via the Float64 type IsNull method. -// -// Setting the deprecated Float64 type Null, Unknown, or Value fields after -// creating a Float64 with this function has no effect. -func Float64Null() Float64 { - return Float64{ +func NewFloat64Null() Float64Value { + return Float64Value{ state: attr.ValueStateNull, } } @@ -41,8 +36,8 @@ func Float64Null() Float64 { // // Setting the deprecated Float64 type Null, Unknown, or Value fields after // creating a Float64 with this function has no effect. -func Float64Unknown() Float64 { - return Float64{ +func NewFloat64Unknown() Float64Value { + return Float64Value{ state: attr.ValueStateUnknown, } } @@ -52,88 +47,15 @@ func Float64Unknown() Float64 { // // Setting the deprecated Float64 type Null, Unknown, or Value fields after // creating a Float64 with this function has no effect. -func Float64Value(value float64) Float64 { - return Float64{ +func NewFloat64Value(value float64) Float64Value { + return Float64Value{ state: attr.ValueStateKnown, value: value, } } -func float64Validate(_ context.Context, in tftypes.Value, path path.Path) diag.Diagnostics { - var diags diag.Diagnostics - - if in.Type() == nil { - return diags - } - - if !in.Type().Equal(tftypes.Number) { - diags.AddAttributeError( - path, - "Float64 Type Validation Error", - "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ - fmt.Sprintf("Expected Number value, received %T with value: %v", in, in), - ) - return diags - } - - if !in.IsKnown() || in.IsNull() { - return diags - } - - var value *big.Float - err := in.As(&value) - - if err != nil { - diags.AddAttributeError( - path, - "Float64 Type Validation Error", - "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ - fmt.Sprintf("Cannot convert value to big.Float: %s", err), - ) - return diags - } - - _, accuracy := value.Float64() - - if accuracy != 0 { - diags.AddAttributeError( - path, - "Float64 Type Validation Error", - fmt.Sprintf("Value %s cannot be represented as a 64-bit floating point.", value), - ) - return diags - } - - return diags -} - -func float64ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { - if !in.IsKnown() { - return Float64Unknown(), nil - } - - if in.IsNull() { - return Float64Null(), nil - } - - var bigF *big.Float - err := in.As(&bigF) - - if err != nil { - return nil, err - } - - f, accuracy := bigF.Float64() - - if accuracy != 0 { - return nil, fmt.Errorf("Value %s cannot be represented as a 64-bit floating point.", bigF) - } - - return Float64Value(f), nil -} - -// Float64 represents a 64-bit floating point value, exposed as a float64. -type Float64 struct { +// Float64Value represents a 64-bit floating point value, exposed as a float64. +type Float64Value struct { // state represents whether the value is null, unknown, or known. The // zero-value is null. state attr.ValueState @@ -143,8 +65,8 @@ type Float64 struct { } // Equal returns true if `other` is a Float64 and has the same value as `f`. -func (f Float64) Equal(other attr.Value) bool { - o, ok := other.(Float64) +func (f Float64Value) Equal(other attr.Value) bool { + o, ok := other.(Float64Value) if !ok { return false @@ -162,7 +84,7 @@ func (f Float64) Equal(other attr.Value) bool { } // ToTerraformValue returns the data contained in the Float64 as a tftypes.Value. -func (f Float64) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { +func (f Float64Value) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { switch f.state { case attr.ValueStateKnown: if err := tftypes.ValidateValue(tftypes.Number, f.value); err != nil { @@ -180,24 +102,24 @@ func (f Float64) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { } // Type returns a Float64Type. -func (f Float64) Type(ctx context.Context) attr.Type { - return Float64Type +func (f Float64Value) Type(ctx context.Context) attr.Type { + return Float64Type{} } // IsNull returns true if the Float64 represents a null value. -func (f Float64) IsNull() bool { +func (f Float64Value) IsNull() bool { return f.state == attr.ValueStateNull } // IsUnknown returns true if the Float64 represents a currently unknown value. -func (f Float64) IsUnknown() bool { +func (f Float64Value) IsUnknown() bool { return f.state == attr.ValueStateUnknown } // String returns a human-readable representation of the Float64 value. // The string returned here is not protected by any compatibility guarantees, // and is intended for logging and error reporting. -func (f Float64) String() string { +func (f Float64Value) String() string { if f.IsUnknown() { return attr.UnknownValueString } @@ -211,11 +133,11 @@ func (f Float64) String() string { // ValueFloat64 returns the known float64 value. If Float64 is null or unknown, returns // 0.0. -func (f Float64) ValueFloat64() float64 { +func (f Float64Value) ValueFloat64() float64 { return f.value } // ToFloat64Value returns Float64. -func (f Float64) ToFloat64Value(context.Context) (Float64, diag.Diagnostics) { +func (f Float64Value) ToFloat64Value(context.Context) (Float64Value, diag.Diagnostics) { return f, nil } diff --git a/types/float64_test.go b/types/basetypes/float64_test.go similarity index 72% rename from types/float64_test.go rename to types/basetypes/float64_test.go index 79c6e0ca9..ab3c9ae26 100644 --- a/types/float64_test.go +++ b/types/basetypes/float64_test.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -11,13 +11,9 @@ import ( "github.com/hashicorp/terraform-plugin-go/tftypes" ) -func TestFloat64ValueFromTerraform(t *testing.T) { +func TestFloat64TypeValueFromTerraform(t *testing.T) { t.Parallel() - testFloat64ValueFromTerraform(t, true) -} - -func testFloat64ValueFromTerraform(t *testing.T, direct bool) { type testCase struct { input tftypes.Value expectation attr.Value @@ -26,19 +22,19 @@ func testFloat64ValueFromTerraform(t *testing.T, direct bool) { tests := map[string]testCase{ "value-int": { input: tftypes.NewValue(tftypes.Number, 123), - expectation: Float64Value(123.0), + expectation: NewFloat64Value(123.0), }, "value-float": { input: tftypes.NewValue(tftypes.Number, 123.456), - expectation: Float64Value(123.456), + expectation: NewFloat64Value(123.456), }, "unknown": { input: tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), - expectation: Float64Unknown(), + expectation: NewFloat64Unknown(), }, "null": { input: tftypes.NewValue(tftypes.Number, nil), - expectation: Float64Null(), + expectation: NewFloat64Null(), }, "wrongType": { input: tftypes.NewValue(tftypes.String, "oops"), @@ -51,11 +47,7 @@ func testFloat64ValueFromTerraform(t *testing.T, direct bool) { t.Parallel() ctx := context.Background() - f := Float64Type.ValueFromTerraform - if direct { - f = float64ValueFromTerraform - } - got, err := f(ctx, test.input) + got, err := Float64Type{}.ValueFromTerraform(ctx, test.input) if err != nil { if test.expectedErr == "" { t.Errorf("Unexpected error: %s", err) @@ -86,44 +78,44 @@ func testFloat64ValueFromTerraform(t *testing.T, direct bool) { } } -func TestFloat64ToTerraformValue(t *testing.T) { +func TestFloat64ValueToTerraformValue(t *testing.T) { t.Parallel() type testCase struct { - input Float64 + input Float64Value expectation interface{} } tests := map[string]testCase{ "known-int": { - input: Float64Value(123), + input: NewFloat64Value(123), expectation: tftypes.NewValue(tftypes.Number, big.NewFloat(123.0)), }, "known-float": { - input: Float64Value(123.456), + input: NewFloat64Value(123.456), expectation: tftypes.NewValue(tftypes.Number, big.NewFloat(123.456)), }, "unknown": { - input: Float64Unknown(), + input: NewFloat64Unknown(), expectation: tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), }, "null": { - input: Float64Null(), + input: NewFloat64Null(), expectation: tftypes.NewValue(tftypes.Number, nil), }, "deprecated-value-int": { - input: Float64Value(123), + input: NewFloat64Value(123), expectation: tftypes.NewValue(tftypes.Number, big.NewFloat(123.0)), }, "deprecated-value-float": { - input: Float64Value(123.456), + input: NewFloat64Value(123.456), expectation: tftypes.NewValue(tftypes.Number, big.NewFloat(123.456)), }, "deprecated-unknown": { - input: Float64Unknown(), + input: NewFloat64Unknown(), expectation: tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), }, "deprecated-null": { - input: Float64Null(), + input: NewFloat64Null(), expectation: tftypes.NewValue(tftypes.Number, nil), }, } @@ -145,63 +137,63 @@ func TestFloat64ToTerraformValue(t *testing.T) { } } -func TestFloat64Equal(t *testing.T) { +func TestFloat64ValueEqual(t *testing.T) { t.Parallel() type testCase struct { - input Float64 + input Float64Value candidate attr.Value expectation bool } tests := map[string]testCase{ "known-known-same": { - input: Float64Value(123), - candidate: Float64Value(123), + input: NewFloat64Value(123), + candidate: NewFloat64Value(123), expectation: true, }, "known-known-diff": { - input: Float64Value(123), - candidate: Float64Value(456), + input: NewFloat64Value(123), + candidate: NewFloat64Value(456), expectation: false, }, "known-unknown": { - input: Float64Value(123), - candidate: Float64Unknown(), + input: NewFloat64Value(123), + candidate: NewFloat64Unknown(), expectation: false, }, "known-null": { - input: Float64Value(123), - candidate: Float64Null(), + input: NewFloat64Value(123), + candidate: NewFloat64Null(), expectation: false, }, "unknown-value": { - input: Float64Unknown(), - candidate: Float64Value(123), + input: NewFloat64Unknown(), + candidate: NewFloat64Value(123), expectation: false, }, "unknown-unknown": { - input: Float64Unknown(), - candidate: Float64Unknown(), + input: NewFloat64Unknown(), + candidate: NewFloat64Unknown(), expectation: true, }, "unknown-null": { - input: Float64Unknown(), - candidate: Float64Null(), + input: NewFloat64Unknown(), + candidate: NewFloat64Null(), expectation: false, }, "null-known": { - input: Float64Null(), - candidate: Float64Value(123), + input: NewFloat64Null(), + candidate: NewFloat64Value(123), expectation: false, }, "null-unknown": { - input: Float64Null(), - candidate: Float64Unknown(), + input: NewFloat64Null(), + candidate: NewFloat64Unknown(), expectation: false, }, "null-null": { - input: Float64Null(), - candidate: Float64Null(), + input: NewFloat64Null(), + candidate: NewFloat64Null(), expectation: true, }, } @@ -218,23 +210,23 @@ func TestFloat64Equal(t *testing.T) { } } -func TestFloat64IsNull(t *testing.T) { +func TestFloat64ValueIsNull(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Float64 + input Float64Value expected bool }{ "known": { - input: Float64Value(2.4), + input: NewFloat64Value(2.4), expected: false, }, "null": { - input: Float64Null(), + input: NewFloat64Null(), expected: true, }, "unknown": { - input: Float64Unknown(), + input: NewFloat64Unknown(), expected: false, }, } @@ -254,23 +246,23 @@ func TestFloat64IsNull(t *testing.T) { } } -func TestFloat64IsUnknown(t *testing.T) { +func TestFloat64ValueIsUnknown(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Float64 + input Float64Value expected bool }{ "known": { - input: Float64Value(2.4), + input: NewFloat64Value(2.4), expected: false, }, "null": { - input: Float64Null(), + input: NewFloat64Null(), expected: false, }, "unknown": { - input: Float64Unknown(), + input: NewFloat64Unknown(), expected: true, }, } @@ -290,48 +282,48 @@ func TestFloat64IsUnknown(t *testing.T) { } } -func TestFloat64String(t *testing.T) { +func TestFloat64ValueString(t *testing.T) { t.Parallel() type testCase struct { - input Float64 + input Float64Value expectation string } tests := map[string]testCase{ "less-than-one": { - input: Float64Value(0.12340984302980000), + input: NewFloat64Value(0.12340984302980000), expectation: "0.123410", }, "more-than-one": { - input: Float64Value(92387938173219.327663), + input: NewFloat64Value(92387938173219.327663), expectation: "92387938173219.328125", }, "negative-more-than-one": { - input: Float64Value(-0.12340984302980000), + input: NewFloat64Value(-0.12340984302980000), expectation: "-0.123410", }, "negative-less-than-one": { - input: Float64Value(-92387938173219.327663), + input: NewFloat64Value(-92387938173219.327663), expectation: "-92387938173219.328125", }, "min-float64": { - input: Float64Value(math.SmallestNonzeroFloat64), + input: NewFloat64Value(math.SmallestNonzeroFloat64), expectation: "0.000000", }, "max-float64": { - input: Float64Value(math.MaxFloat64), + input: NewFloat64Value(math.MaxFloat64), expectation: "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000", }, "unknown": { - input: Float64Unknown(), + input: NewFloat64Unknown(), expectation: "", }, "null": { - input: Float64Null(), + input: NewFloat64Null(), expectation: "", }, "zero-value": { - input: Float64{}, + input: Float64Value{}, expectation: "", }, } @@ -349,23 +341,23 @@ func TestFloat64String(t *testing.T) { } } -func TestFloat64ValueFloat64(t *testing.T) { +func TestFloat64ValueValueFloat64(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Float64 + input Float64Value expected float64 }{ "known": { - input: Float64Value(2.4), + input: NewFloat64Value(2.4), expected: 2.4, }, "null": { - input: Float64Null(), + input: NewFloat64Null(), expected: 0.0, }, "unknown": { - input: Float64Unknown(), + input: NewFloat64Unknown(), expected: 0.0, }, } diff --git a/types/basetypes/float64_type.go b/types/basetypes/float64_type.go new file mode 100644 index 000000000..3831fdfec --- /dev/null +++ b/types/basetypes/float64_type.go @@ -0,0 +1,140 @@ +package basetypes + +import ( + "context" + "fmt" + "math/big" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Float64Typable extends attr.Type for float64 types. +// Implement this interface to create a custom Float64Type type. +type Float64Typable interface { + xattr.TypeWithValidate + + // ValueFromFloat64 should convert the Float64 to a Float64Valuable type. + ValueFromFloat64(context.Context, Float64Value) (Float64Valuable, diag.Diagnostics) +} + +var _ Float64Typable = Float64Type{} + +// Float64Type is the base framework type for a floating point number. +// Float64Value is the associated value type. +type Float64Type struct{} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// type. +func (t Float64Type) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// Equal returns true if the given type is equivalent. +func (t Float64Type) Equal(o attr.Type) bool { + _, ok := o.(Float64Type) + + return ok +} + +// String returns a human readable string of the type name. +func (t Float64Type) String() string { + return "basetypes.Float64Type" +} + +// TerraformType returns the tftypes.Type that should be used to represent this +// framework type. +func (t Float64Type) TerraformType(_ context.Context) tftypes.Type { + return tftypes.Number +} + +// Validate implements type validation. +func (t Float64Type) Validate(ctx context.Context, in tftypes.Value, path path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + if in.Type() == nil { + return diags + } + + if !in.Type().Equal(tftypes.Number) { + diags.AddAttributeError( + path, + "Float64 Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Expected Number value, received %T with value: %v", in, in), + ) + return diags + } + + if !in.IsKnown() || in.IsNull() { + return diags + } + + var value *big.Float + err := in.As(&value) + + if err != nil { + diags.AddAttributeError( + path, + "Float64 Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Cannot convert value to big.Float: %s", err), + ) + return diags + } + + _, accuracy := value.Float64() + + if accuracy != 0 { + diags.AddAttributeError( + path, + "Float64 Type Validation Error", + fmt.Sprintf("Value %s cannot be represented as a 64-bit floating point.", value), + ) + return diags + } + + return diags +} + +// ValueFromFloat64 returns a Float64Valuable type given a Float64Value. +func (t Float64Type) ValueFromFloat64(_ context.Context, v Float64Value) (Float64Valuable, diag.Diagnostics) { + return v, nil +} + +// ValueFromTerraform returns a Value given a tftypes.Value. This is meant to +// convert the tftypes.Value into a more convenient Go type for the provider to +// consume the data with. +func (t Float64Type) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if !in.IsKnown() { + return NewFloat64Unknown(), nil + } + + if in.IsNull() { + return NewFloat64Null(), nil + } + + var bigF *big.Float + err := in.As(&bigF) + + if err != nil { + return nil, err + } + + f, accuracy := bigF.Float64() + + if accuracy != 0 { + return nil, fmt.Errorf("Value %s cannot be represented as a 64-bit floating point.", bigF) + } + + return NewFloat64Value(f), nil +} + +// ValueType returns the Value type. +func (t Float64Type) ValueType(_ context.Context) attr.Value { + // This Value does not need to be valid. + return Float64Value{} +} diff --git a/types/basetypes/int64.go b/types/basetypes/int64.go new file mode 100644 index 000000000..d924c5b97 --- /dev/null +++ b/types/basetypes/int64.go @@ -0,0 +1,137 @@ +package basetypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" +) + +var ( + _ Int64Valuable = Int64Value{} +) + +// Int64Valuable extends attr.Value for int64 value types. +// Implement this interface to create a custom Int64 value type. +type Int64Valuable interface { + attr.Value + + // ToInt64Value should convert the value type to an Int64. + ToInt64Value(ctx context.Context) (Int64Value, diag.Diagnostics) +} + +// NewInt64Null creates a Int64 with a null value. Determine whether the value is +// null via the Int64 type IsNull method. +func NewInt64Null() Int64Value { + return Int64Value{ + state: attr.ValueStateNull, + } +} + +// NewInt64Unknown creates a Int64 with an unknown value. Determine whether the +// value is unknown via the Int64 type IsUnknown method. +func NewInt64Unknown() Int64Value { + return Int64Value{ + state: attr.ValueStateUnknown, + } +} + +// NewInt64Value creates a Int64 with a known value. Access the value via the Int64 +// type ValueInt64 method. +func NewInt64Value(value int64) Int64Value { + return Int64Value{ + state: attr.ValueStateKnown, + value: value, + } +} + +// Int64Value represents a 64-bit integer value, exposed as an int64. +type Int64Value struct { + // state represents whether the value is null, unknown, or known. The + // zero-value is null. + state attr.ValueState + + // value contains the known value, if not null or unknown. + value int64 +} + +// Equal returns true if `other` is an Int64 and has the same value as `i`. +func (i Int64Value) Equal(other attr.Value) bool { + o, ok := other.(Int64Value) + + if !ok { + return false + } + + if i.state != o.state { + return false + } + + if i.state != attr.ValueStateKnown { + return true + } + + return i.value == o.value +} + +// ToTerraformValue returns the data contained in the Int64 as a tftypes.Value. +func (i Int64Value) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + switch i.state { + case attr.ValueStateKnown: + if err := tftypes.ValidateValue(tftypes.Number, i.value); err != nil { + return tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), err + } + + return tftypes.NewValue(tftypes.Number, i.value), nil + case attr.ValueStateNull: + return tftypes.NewValue(tftypes.Number, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Int64 state in ToTerraformValue: %s", i.state)) + } +} + +// Type returns a Int64Type. +func (i Int64Value) Type(ctx context.Context) attr.Type { + return Int64Type{} +} + +// IsNull returns true if the Int64 represents a null value. +func (i Int64Value) IsNull() bool { + return i.state == attr.ValueStateNull +} + +// IsUnknown returns true if the Int64 represents a currently unknown value. +func (i Int64Value) IsUnknown() bool { + return i.state == attr.ValueStateUnknown +} + +// String returns a human-readable representation of the Int64 value. +// The string returned here is not protected by any compatibility guarantees, +// and is intended for logging and error reporting. +func (i Int64Value) String() string { + if i.IsUnknown() { + return attr.UnknownValueString + } + + if i.IsNull() { + return attr.NullValueString + } + + return fmt.Sprintf("%d", i.value) +} + +// ValueInt64 returns the known float64 value. If Int64 is null or unknown, returns +// 0.0. +func (i Int64Value) ValueInt64() int64 { + return i.value +} + +// ToInt64Value returns Int64. +func (i Int64Value) ToInt64Value(context.Context) (Int64Value, diag.Diagnostics) { + return i, nil +} diff --git a/types/int64_test.go b/types/basetypes/int64_test.go similarity index 73% rename from types/int64_test.go rename to types/basetypes/int64_test.go index 0271b6cbc..86c7dfe69 100644 --- a/types/int64_test.go +++ b/types/basetypes/int64_test.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -11,13 +11,9 @@ import ( "github.com/hashicorp/terraform-plugin-go/tftypes" ) -func TestInt64ValueFromTerraform(t *testing.T) { +func TestInt64TypeValueFromTerraform(t *testing.T) { t.Parallel() - testInt64ValueFromTerraform(t, true) -} - -func testInt64ValueFromTerraform(t *testing.T, direct bool) { type testCase struct { input tftypes.Value expectation attr.Value @@ -26,15 +22,15 @@ func testInt64ValueFromTerraform(t *testing.T, direct bool) { tests := map[string]testCase{ "value": { input: tftypes.NewValue(tftypes.Number, 123), - expectation: Int64Value(123), + expectation: NewInt64Value(123), }, "unknown": { input: tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), - expectation: Int64Unknown(), + expectation: NewInt64Unknown(), }, "null": { input: tftypes.NewValue(tftypes.Number, nil), - expectation: Int64Null(), + expectation: NewInt64Null(), }, "wrongType": { input: tftypes.NewValue(tftypes.String, "oops"), @@ -47,11 +43,7 @@ func testInt64ValueFromTerraform(t *testing.T, direct bool) { t.Parallel() ctx := context.Background() - f := Int64Type.ValueFromTerraform - if direct { - f = int64ValueFromTerraform - } - got, err := f(ctx, test.input) + got, err := Int64Type{}.ValueFromTerraform(ctx, test.input) if err != nil { if test.expectedErr == "" { t.Errorf("Unexpected error: %s", err) @@ -82,24 +74,24 @@ func testInt64ValueFromTerraform(t *testing.T, direct bool) { } } -func TestInt64ToTerraformValue(t *testing.T) { +func TestInt64ValueToTerraformValue(t *testing.T) { t.Parallel() type testCase struct { - input Int64 + input Int64Value expectation interface{} } tests := map[string]testCase{ "known": { - input: Int64Value(123), + input: NewInt64Value(123), expectation: tftypes.NewValue(tftypes.Number, big.NewFloat(123)), }, "unknown": { - input: Int64Unknown(), + input: NewInt64Unknown(), expectation: tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), }, "null": { - input: Int64Null(), + input: NewInt64Null(), expectation: tftypes.NewValue(tftypes.Number, nil), }, } @@ -121,63 +113,63 @@ func TestInt64ToTerraformValue(t *testing.T) { } } -func TestInt64Equal(t *testing.T) { +func TestInt64ValueEqual(t *testing.T) { t.Parallel() type testCase struct { - input Int64 + input Int64Value candidate attr.Value expectation bool } tests := map[string]testCase{ "known-known-same": { - input: Int64Value(123), - candidate: Int64Value(123), + input: NewInt64Value(123), + candidate: NewInt64Value(123), expectation: true, }, "known-known-diff": { - input: Int64Value(123), - candidate: Int64Value(456), + input: NewInt64Value(123), + candidate: NewInt64Value(456), expectation: false, }, "known-unknown": { - input: Int64Value(123), - candidate: Int64Unknown(), + input: NewInt64Value(123), + candidate: NewInt64Unknown(), expectation: false, }, "known-null": { - input: Int64Value(123), - candidate: Int64Null(), + input: NewInt64Value(123), + candidate: NewInt64Null(), expectation: false, }, "unknown-value": { - input: Int64Unknown(), - candidate: Int64Value(123), + input: NewInt64Unknown(), + candidate: NewInt64Value(123), expectation: false, }, "unknown-unknown": { - input: Int64Unknown(), - candidate: Int64Unknown(), + input: NewInt64Unknown(), + candidate: NewInt64Unknown(), expectation: true, }, "unknown-null": { - input: Int64Unknown(), - candidate: Int64Null(), + input: NewInt64Unknown(), + candidate: NewInt64Null(), expectation: false, }, "null-known": { - input: Int64Null(), - candidate: Int64Value(123), + input: NewInt64Null(), + candidate: NewInt64Value(123), expectation: false, }, "null-unknown": { - input: Int64Null(), - candidate: Int64Unknown(), + input: NewInt64Null(), + candidate: NewInt64Unknown(), expectation: false, }, "null-null": { - input: Int64Null(), - candidate: Int64Null(), + input: NewInt64Null(), + candidate: NewInt64Null(), expectation: true, }, } @@ -194,23 +186,23 @@ func TestInt64Equal(t *testing.T) { } } -func TestInt64IsNull(t *testing.T) { +func TestInt64ValueIsNull(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Int64 + input Int64Value expected bool }{ "known": { - input: Int64Value(24), + input: NewInt64Value(24), expected: false, }, "null": { - input: Int64Null(), + input: NewInt64Null(), expected: true, }, "unknown": { - input: Int64Unknown(), + input: NewInt64Unknown(), expected: false, }, } @@ -230,23 +222,23 @@ func TestInt64IsNull(t *testing.T) { } } -func TestInt64IsUnknown(t *testing.T) { +func TestInt64ValueIsUnknown(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Int64 + input Int64Value expected bool }{ "known": { - input: Int64Value(24), + input: NewInt64Value(24), expected: false, }, "null": { - input: Int64Null(), + input: NewInt64Null(), expected: false, }, "unknown": { - input: Int64Unknown(), + input: NewInt64Unknown(), expected: true, }, } @@ -266,40 +258,40 @@ func TestInt64IsUnknown(t *testing.T) { } } -func TestInt64String(t *testing.T) { +func TestInt64ValueString(t *testing.T) { t.Parallel() type testCase struct { - input Int64 + input Int64Value expectation string } tests := map[string]testCase{ "known-less-than-one": { - input: Int64Value(-12340984302980000), + input: NewInt64Value(-12340984302980000), expectation: "-12340984302980000", }, "known-more-than-one": { - input: Int64Value(92387938173219327), + input: NewInt64Value(92387938173219327), expectation: "92387938173219327", }, "known-min-int64": { - input: Int64Value(math.MinInt64), + input: NewInt64Value(math.MinInt64), expectation: "-9223372036854775808", }, "known-max-int64": { - input: Int64Value(math.MaxInt64), + input: NewInt64Value(math.MaxInt64), expectation: "9223372036854775807", }, "unknown": { - input: Int64Unknown(), + input: NewInt64Unknown(), expectation: "", }, "null": { - input: Int64Null(), + input: NewInt64Null(), expectation: "", }, "zero-value": { - input: Int64{}, + input: Int64Value{}, expectation: "", }, } @@ -317,23 +309,23 @@ func TestInt64String(t *testing.T) { } } -func TestInt64ValueInt64(t *testing.T) { +func TestInt64ValueValueInt64(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Int64 + input Int64Value expected int64 }{ "known": { - input: Int64Value(24), + input: NewInt64Value(24), expected: 24, }, "null": { - input: Int64Null(), + input: NewInt64Null(), expected: 0, }, "unknown": { - input: Int64Unknown(), + input: NewInt64Unknown(), expected: 0, }, } diff --git a/types/basetypes/int64_type.go b/types/basetypes/int64_type.go new file mode 100644 index 000000000..91c9fdceb --- /dev/null +++ b/types/basetypes/int64_type.go @@ -0,0 +1,153 @@ +package basetypes + +import ( + "context" + "fmt" + "math/big" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/attr/xattr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// Int64Typable extends attr.Type for int64 types. +// Implement this interface to create a custom Int64Type type. +type Int64Typable interface { + xattr.TypeWithValidate + + // ValueFromInt64 should convert the Int64 to a Int64Valuable type. + ValueFromInt64(context.Context, Int64Value) (Int64Valuable, diag.Diagnostics) +} + +var _ Int64Typable = Int64Type{} + +// Int64Type is the base framework type for an integer number. +// Int64Value is the associated value type. +type Int64Type struct{} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// type. +func (t Int64Type) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// Equal returns true if the given type is equivalent. +func (t Int64Type) Equal(o attr.Type) bool { + _, ok := o.(Int64Type) + + return ok +} + +// String returns a human readable string of the type name. +func (t Int64Type) String() string { + return "basetypes.Int64Type" +} + +// TerraformType returns the tftypes.Type that should be used to represent this +// framework type. +func (t Int64Type) TerraformType(_ context.Context) tftypes.Type { + return tftypes.Number +} + +// Validate implements type validation. +func (t Int64Type) Validate(ctx context.Context, in tftypes.Value, path path.Path) diag.Diagnostics { + var diags diag.Diagnostics + + if in.Type() == nil { + return diags + } + + if !in.Type().Equal(tftypes.Number) { + diags.AddAttributeError( + path, + "Int64 Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Expected Number value, received %T with value: %v", in, in), + ) + return diags + } + + if !in.IsKnown() || in.IsNull() { + return diags + } + + var value *big.Float + err := in.As(&value) + + if err != nil { + diags.AddAttributeError( + path, + "Int64 Type Validation Error", + "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ + fmt.Sprintf("Cannot convert value to big.Float: %s", err), + ) + return diags + } + + if !value.IsInt() { + diags.AddAttributeError( + path, + "Int64 Type Validation Error", + fmt.Sprintf("Value %s is not an integer.", value), + ) + return diags + } + + _, accuracy := value.Int64() + + if accuracy != 0 { + diags.AddAttributeError( + path, + "Int64 Type Validation Error", + fmt.Sprintf("Value %s cannot be represented as a 64-bit integer.", value), + ) + return diags + } + + return diags +} + +// ValueFromInt64 returns a Int64Valuable type given a Int64Value. +func (t Int64Type) ValueFromInt64(_ context.Context, v Int64Value) (Int64Valuable, diag.Diagnostics) { + return v, nil +} + +// ValueFromTerraform returns a Value given a tftypes.Value. This is meant to +// convert the tftypes.Value into a more convenient Go type for the provider to +// consume the data with. +func (t Int64Type) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if !in.IsKnown() { + return NewInt64Unknown(), nil + } + + if in.IsNull() { + return NewInt64Null(), nil + } + + var bigF *big.Float + err := in.As(&bigF) + + if err != nil { + return nil, err + } + + if !bigF.IsInt() { + return nil, fmt.Errorf("Value %s is not an integer.", bigF) + } + + i, accuracy := bigF.Int64() + + if accuracy != 0 { + return nil, fmt.Errorf("Value %s cannot be represented as a 64-bit integer.", bigF) + } + + return NewInt64Value(i), nil +} + +// ValueType returns the Value type. +func (t Int64Type) ValueType(_ context.Context) attr.Value { + // This Value does not need to be valid. + return Int64Value{} +} diff --git a/types/list.go b/types/basetypes/list.go similarity index 81% rename from types/list.go rename to types/basetypes/list.go index 31c40232e..1b4b96100 100644 --- a/types/list.go +++ b/types/basetypes/list.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -16,7 +16,7 @@ import ( var ( _ ListTypable = ListType{} - _ ListValuable = &List{} + _ ListValuable = &ListValue{} ) // ListTypable extends attr.Type for list types. @@ -25,7 +25,7 @@ type ListTypable interface { attr.Type // ValueFromList should convert the List to a ListValuable type. - ValueFromList(context.Context, List) (ListValuable, diag.Diagnostics) + ValueFromList(context.Context, ListValue) (ListValuable, diag.Diagnostics) } // ListValuable extends attr.Value for list value types. @@ -34,7 +34,7 @@ type ListValuable interface { attr.Value // ToListValue should convert the value type to a List. - ToListValue(ctx context.Context) (List, diag.Diagnostics) + ToListValue(ctx context.Context) (ListValue, diag.Diagnostics) } // ListType is an AttributeType representing a list of values. All values must @@ -71,16 +71,16 @@ func (l ListType) TerraformType(ctx context.Context) tftypes.Type { // type for the provider to consume the data with. func (l ListType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { if in.Type() == nil { - return ListNull(l.ElemType), nil + return NewListNull(l.ElemType), nil } if !in.Type().Equal(l.TerraformType(ctx)) { return nil, fmt.Errorf("can't use %s as value of List with ElementType %T, can only use %s values", in.String(), l.ElemType, l.ElemType.TerraformType(ctx).String()) } if !in.IsKnown() { - return ListUnknown(l.ElemType), nil + return NewListUnknown(l.ElemType), nil } if in.IsNull() { - return ListNull(l.ElemType), nil + return NewListNull(l.ElemType), nil } val := []tftypes.Value{} err := in.As(&val) @@ -97,7 +97,7 @@ func (l ListType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (att } // ValueFromTerraform above on each element should make this safe. // Otherwise, this will need to do some Diagnostics to error conversion. - return ListValueMust(l.ElemType, elems), nil + return NewListValueMust(l.ElemType, elems), nil } // Equal returns true if `o` is also a ListType and has the same ElemType. @@ -178,37 +178,37 @@ func (l ListType) Validate(ctx context.Context, in tftypes.Value, path path.Path // ValueType returns the Value type. func (l ListType) ValueType(_ context.Context) attr.Value { - return List{ + return ListValue{ elementType: l.ElemType, } } // ValueFromList returns a ListValuable type given a List. -func (l ListType) ValueFromList(_ context.Context, list List) (ListValuable, diag.Diagnostics) { +func (l ListType) ValueFromList(_ context.Context, list ListValue) (ListValuable, diag.Diagnostics) { return list, nil } -// ListNull creates a List with a null value. Determine whether the value is +// NewListNull creates a List with a null value. Determine whether the value is // null via the List type IsNull method. -func ListNull(elementType attr.Type) List { - return List{ +func NewListNull(elementType attr.Type) ListValue { + return ListValue{ elementType: elementType, state: attr.ValueStateNull, } } -// ListUnknown creates a List with an unknown value. Determine whether the +// NewListUnknown creates a List with an unknown value. Determine whether the // value is unknown via the List type IsUnknown method. -func ListUnknown(elementType attr.Type) List { - return List{ +func NewListUnknown(elementType attr.Type) ListValue { + return ListValue{ elementType: elementType, state: attr.ValueStateUnknown, } } -// ListValue creates a List with a known value. Access the value via the List +// NewListValue creates a List with a known value. Access the value via the List // type Elements or ElementsAs methods. -func ListValue(elementType attr.Type, elements []attr.Value) (List, diag.Diagnostics) { +func NewListValue(elementType attr.Type, elements []attr.Value) (ListValue, diag.Diagnostics) { var diags diag.Diagnostics // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 @@ -228,20 +228,20 @@ func ListValue(elementType attr.Type, elements []attr.Value) (List, diag.Diagnos } if diags.HasError() { - return ListUnknown(elementType), diags + return NewListUnknown(elementType), diags } - return List{ + return ListValue{ elementType: elementType, elements: elements, state: attr.ValueStateKnown, }, nil } -// ListValueFrom creates a List with a known value, using reflection rules. +// NewListValueFrom creates a List with a known value, using reflection rules. // The elements must be a slice which can convert into the given element type. // Access the value via the List type Elements or ElementsAs methods. -func ListValueFrom(ctx context.Context, elementType attr.Type, elements any) (List, diag.Diagnostics) { +func NewListValueFrom(ctx context.Context, elementType attr.Type, elements any) (ListValue, diag.Diagnostics) { attrValue, diags := reflect.FromValue( ctx, ListType{ElemType: elementType}, @@ -250,16 +250,16 @@ func ListValueFrom(ctx context.Context, elementType attr.Type, elements any) (Li ) if diags.HasError() { - return ListUnknown(elementType), diags + return NewListUnknown(elementType), diags } - list, ok := attrValue.(List) + list, ok := attrValue.(ListValue) // This should not happen, but ensure there is an error if it does. if !ok { diags.AddError( "Unable to Convert List Value", - "An unexpected result occurred when creating a List using ListValueFrom. "+ + "An unexpected result occurred when creating a List using NewListValueFrom. "+ "This is an issue with terraform-plugin-framework and should be reported to the provider developers.", ) } @@ -267,15 +267,15 @@ func ListValueFrom(ctx context.Context, elementType attr.Type, elements any) (Li return list, diags } -// ListValueMust creates a List with a known value, converting any diagnostics +// NewListValueMust creates a List with a known value, converting any diagnostics // into a panic at runtime. Access the value via the List // type Elements or ElementsAs methods. // // This creation function is only recommended to create List values which will // not potentially affect practitioners, such as testing, or exhaustively // tested provider logic. -func ListValueMust(elementType attr.Type, elements []attr.Value) List { - list, diags := ListValue(elementType, elements) +func NewListValueMust(elementType attr.Type, elements []attr.Value) ListValue { + list, diags := NewListValue(elementType, elements) if diags.HasError() { // This could potentially be added to the diag package. @@ -289,15 +289,15 @@ func ListValueMust(elementType attr.Type, elements []attr.Value) List { diagnostic.Detail())) } - panic("ListValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + panic("NewListValueMust received error(s): " + strings.Join(diagsStrings, "\n")) } return list } -// List represents a list of attr.Values, all of the same type, indicated +// ListValue represents a list of attr.Values, all of the same type, indicated // by ElemType. -type List struct { +type ListValue struct { // elements is the collection of known values in the List. elements []attr.Value @@ -311,13 +311,13 @@ type List struct { // Elements returns the collection of elements for the List. Returns nil if the // List is null or unknown. -func (l List) Elements() []attr.Value { +func (l ListValue) Elements() []attr.Value { return l.elements } -// ElementsAs populates `target` with the elements of the List, throwing an +// ElementsAs populates `target` with the elements of the ListValue, throwing an // error if the elements cannot be stored in `target`. -func (l List) ElementsAs(ctx context.Context, target interface{}, allowUnhandled bool) diag.Diagnostics { +func (l ListValue) ElementsAs(ctx context.Context, target interface{}, allowUnhandled bool) diag.Diagnostics { // we need a tftypes.Value for this List to be able to use it with our // reflection code values, err := l.ToTerraformValue(ctx) @@ -336,17 +336,17 @@ func (l List) ElementsAs(ctx context.Context, target interface{}, allowUnhandled } // ElementType returns the element type for the List. -func (l List) ElementType(_ context.Context) attr.Type { +func (l ListValue) ElementType(_ context.Context) attr.Type { return l.elementType } // Type returns a ListType with the same element type as `l`. -func (l List) Type(ctx context.Context) attr.Type { +func (l ListValue) Type(ctx context.Context) attr.Type { return ListType{ElemType: l.ElementType(ctx)} } // ToTerraformValue returns the data contained in the List as a tftypes.Value. -func (l List) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { +func (l ListValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { listType := tftypes.List{ElementType: l.ElementType(ctx).TerraformType(ctx)} switch l.state { @@ -379,8 +379,8 @@ func (l List) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { // Equal returns true if the List is considered semantically equal // (same type and same value) to the attr.Value passed as an argument. -func (l List) Equal(o attr.Value) bool { - other, ok := o.(List) +func (l ListValue) Equal(o attr.Value) bool { + other, ok := o.(ListValue) if !ok { return false @@ -414,21 +414,21 @@ func (l List) Equal(o attr.Value) bool { } // IsNull returns true if the List represents a null value. -func (l List) IsNull() bool { +func (l ListValue) IsNull() bool { return l.state == attr.ValueStateNull } // IsUnknown returns true if the List represents a currently unknown value. // Returns false if the List has a known number of elements, even if all are // unknown values. -func (l List) IsUnknown() bool { +func (l ListValue) IsUnknown() bool { return l.state == attr.ValueStateUnknown } // String returns a human-readable representation of the List value. // The string returned here is not protected by any compatibility guarantees, // and is intended for logging and error reporting. -func (l List) String() string { +func (l ListValue) String() string { if l.IsUnknown() { return attr.UnknownValueString } @@ -452,6 +452,6 @@ func (l List) String() string { } // ToListValue returns the List. -func (l List) ToListValue(context.Context) (List, diag.Diagnostics) { +func (l ListValue) ToListValue(context.Context) (ListValue, diag.Diagnostics) { return l, nil } diff --git a/types/list_test.go b/types/basetypes/list_test.go similarity index 66% rename from types/list_test.go rename to types/basetypes/list_test.go index 202a841b3..9c5b8eae9 100644 --- a/types/list_test.go +++ b/types/basetypes/list_test.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -21,7 +21,7 @@ func TestListTypeTerraformType(t *testing.T) { tests := map[string]testCase{ "list-of-strings": { input: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, expected: tftypes.List{ ElementType: tftypes.String, @@ -30,7 +30,7 @@ func TestListTypeTerraformType(t *testing.T) { "list-of-list-of-strings": { input: ListType{ ElemType: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }, expected: tftypes.List{ @@ -43,7 +43,7 @@ func TestListTypeTerraformType(t *testing.T) { input: ListType{ ElemType: ListType{ ElemType: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }, }, @@ -79,7 +79,7 @@ func TestListTypeValueFromTerraform(t *testing.T) { tests := map[string]testCase{ "list-of-strings": { receiver: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.List{ ElementType: tftypes.String, @@ -87,26 +87,26 @@ func TestListTypeValueFromTerraform(t *testing.T) { tftypes.NewValue(tftypes.String, "hello"), tftypes.NewValue(tftypes.String, "world"), }), - expected: ListValueMust( - StringType, + expected: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), }, "unknown-list": { receiver: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.List{ ElementType: tftypes.String, }, tftypes.UnknownValue), - expected: ListUnknown(StringType), + expected: NewListUnknown(StringType{}), }, "partially-unknown-list": { receiver: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.List{ ElementType: tftypes.String, @@ -114,26 +114,26 @@ func TestListTypeValueFromTerraform(t *testing.T) { tftypes.NewValue(tftypes.String, "hello"), tftypes.NewValue(tftypes.String, tftypes.UnknownValue), }), - expected: ListValueMust( - StringType, + expected: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringUnknown(), + NewStringValue("hello"), + NewStringUnknown(), }, ), }, "null-list": { receiver: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.List{ ElementType: tftypes.String, }, nil), - expected: ListNull(StringType), + expected: NewListNull(StringType{}), }, "partially-null-list": { receiver: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.List{ ElementType: tftypes.String, @@ -141,38 +141,38 @@ func TestListTypeValueFromTerraform(t *testing.T) { tftypes.NewValue(tftypes.String, "hello"), tftypes.NewValue(tftypes.String, nil), }), - expected: ListValueMust( - StringType, + expected: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringNull(), + NewStringValue("hello"), + NewStringNull(), }, ), }, "wrong-type": { receiver: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.String, "wrong"), - expectedErr: `can't use tftypes.String<"wrong"> as value of List with ElementType types.primitive, can only use tftypes.String values`, + expectedErr: `can't use tftypes.String<"wrong"> as value of List with ElementType basetypes.StringType, can only use tftypes.String values`, }, "wrong-element-type": { receiver: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.List{ ElementType: tftypes.Number, }, []tftypes.Value{ tftypes.NewValue(tftypes.Number, 1), }), - expectedErr: `can't use tftypes.List[tftypes.Number]> as value of List with ElementType types.primitive, can only use tftypes.String values`, + expectedErr: `can't use tftypes.List[tftypes.Number]> as value of List with ElementType basetypes.StringType, can only use tftypes.String values`, }, "nil-type": { receiver: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(nil, nil), - expected: ListNull(StringType), + expected: NewListNull(StringType{}), }, } for name, test := range tests { @@ -216,22 +216,22 @@ func TestListTypeEqual(t *testing.T) { } tests := map[string]testCase{ "equal": { - receiver: ListType{ElemType: StringType}, - input: ListType{ElemType: StringType}, + receiver: ListType{ElemType: StringType{}}, + input: ListType{ElemType: StringType{}}, expected: true, }, "diff": { - receiver: ListType{ElemType: StringType}, - input: ListType{ElemType: NumberType}, + receiver: ListType{ElemType: StringType{}}, + input: ListType{ElemType: NumberType{}}, expected: false, }, "wrongType": { - receiver: ListType{ElemType: StringType}, - input: NumberType, + receiver: ListType{ElemType: StringType{}}, + input: NumberType{}, expected: false, }, "nil": { - receiver: ListType{ElemType: StringType}, + receiver: ListType{ElemType: StringType{}}, input: nil, expected: false, }, @@ -256,51 +256,51 @@ func TestListTypeEqual(t *testing.T) { } } -func TestListValue(t *testing.T) { +func TestNewListValue(t *testing.T) { t.Parallel() testCases := map[string]struct { elementType attr.Type elements []attr.Value - expected List + expected ListValue expectedDiags diag.Diagnostics }{ "valid-no-elements": { - elementType: StringType, + elementType: StringType{}, elements: []attr.Value{}, - expected: ListValueMust(StringType, []attr.Value{}), + expected: NewListValueMust(StringType{}, []attr.Value{}), }, "valid-elements": { - elementType: StringType, + elementType: StringType{}, elements: []attr.Value{ - StringNull(), - StringUnknown(), - StringValue("test"), + NewStringNull(), + NewStringUnknown(), + NewStringValue("test"), }, - expected: ListValueMust( - StringType, + expected: NewListValueMust( + StringType{}, []attr.Value{ - StringNull(), - StringUnknown(), - StringValue("test"), + NewStringNull(), + NewStringUnknown(), + NewStringValue("test"), }, ), }, "invalid-element-type": { - elementType: StringType, + elementType: StringType{}, elements: []attr.Value{ - StringValue("test"), - BoolValue(true), + NewStringValue("test"), + NewBoolValue(true), }, - expected: ListUnknown(StringType), + expected: NewListUnknown(StringType{}), expectedDiags: diag.Diagnostics{ diag.NewErrorDiagnostic( "Invalid List Element Type", "While creating a List value, an invalid element was detected. "+ "A List must use the single, given element type. "+ "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ - "List Element Type: types.StringType\n"+ - "List Index (1) Element Type: types.BoolType", + "List Element Type: basetypes.StringType\n"+ + "List Index (1) Element Type: basetypes.BoolType", ), }, }, @@ -312,7 +312,7 @@ func TestListValue(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - got, diags := ListValue(testCase.elementType, testCase.elements) + got, diags := NewListValue(testCase.elementType, testCase.elements) if diff := cmp.Diff(got, testCase.expected); diff != "" { t.Errorf("unexpected difference: %s", diff) @@ -325,81 +325,81 @@ func TestListValue(t *testing.T) { } } -func TestListValueFrom(t *testing.T) { +func TestNewListValueFrom(t *testing.T) { t.Parallel() testCases := map[string]struct { elementType attr.Type elements any - expected List + expected ListValue expectedDiags diag.Diagnostics }{ - "valid-StringType-[]attr.Value-empty": { - elementType: StringType, + "valid-StringType{}-[]attr.Value-empty": { + elementType: StringType{}, elements: []attr.Value{}, - expected: ListValueMust( - StringType, + expected: NewListValueMust( + StringType{}, []attr.Value{}, ), }, - "valid-StringType-[]types.String-empty": { - elementType: StringType, - elements: []String{}, - expected: ListValueMust( - StringType, + "valid-StringType{}-[]types.String-empty": { + elementType: StringType{}, + elements: []StringValue{}, + expected: NewListValueMust( + StringType{}, []attr.Value{}, ), }, - "valid-StringType-[]types.String": { - elementType: StringType, - elements: []String{ - StringNull(), - StringUnknown(), - StringValue("test"), + "valid-StringType{}-[]types.String": { + elementType: StringType{}, + elements: []StringValue{ + NewStringNull(), + NewStringUnknown(), + NewStringValue("test"), }, - expected: ListValueMust( - StringType, + expected: NewListValueMust( + StringType{}, []attr.Value{ - StringNull(), - StringUnknown(), - StringValue("test"), + NewStringNull(), + NewStringUnknown(), + NewStringValue("test"), }, ), }, - "valid-StringType-[]*string": { - elementType: StringType, + "valid-StringType{}-[]*string": { + elementType: StringType{}, elements: []*string{ nil, pointer("test1"), pointer("test2"), }, - expected: ListValueMust( - StringType, + expected: NewListValueMust( + StringType{}, []attr.Value{ - StringNull(), - StringValue("test1"), - StringValue("test2"), + NewStringNull(), + NewStringValue("test1"), + NewStringValue("test2"), }, ), }, - "valid-StringType-[]string": { - elementType: StringType, + "valid-StringType{}-[]string": { + elementType: StringType{}, elements: []string{ "test1", "test2", }, - expected: ListValueMust( - StringType, + expected: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("test1"), - StringValue("test2"), + NewStringValue("test1"), + NewStringValue("test2"), }, ), }, "invalid-not-slice": { - elementType: StringType, + elementType: StringType{}, elements: "oops", - expected: ListUnknown(StringType), + expected: NewListUnknown(StringType{}), expectedDiags: diag.Diagnostics{ diag.NewAttributeErrorDiagnostic( path.Empty(), @@ -410,9 +410,9 @@ func TestListValueFrom(t *testing.T) { }, }, "invalid-type": { - elementType: StringType, + elementType: StringType{}, elements: []bool{true}, - expected: ListUnknown(StringType), + expected: NewListUnknown(StringType{}), expectedDiags: diag.Diagnostics{ diag.NewAttributeErrorDiagnostic( path.Empty().AtListIndex(0), @@ -430,7 +430,7 @@ func TestListValueFrom(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - got, diags := ListValueFrom(context.Background(), testCase.elementType, testCase.elements) + got, diags := NewListValueFrom(context.Background(), testCase.elementType, testCase.elements) if diff := cmp.Diff(got, testCase.expected); diff != "" { t.Errorf("unexpected difference: %s", diff) @@ -449,11 +449,11 @@ func TestListElementsAs_stringSlice(t *testing.T) { var stringSlice []string expected := []string{"hello", "world"} - diags := ListValueMust( - StringType, + diags := NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ).ElementsAs(context.Background(), &stringSlice, false) if diags.HasError() { @@ -467,17 +467,17 @@ func TestListElementsAs_stringSlice(t *testing.T) { func TestListElementsAs_attributeValueSlice(t *testing.T) { t.Parallel() - var stringSlice []String - expected := []String{ - StringValue("hello"), - StringValue("world"), + var stringSlice []StringValue + expected := []StringValue{ + NewStringValue("hello"), + NewStringValue("world"), } - diags := ListValueMust( - StringType, + diags := NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ).ElementsAs(context.Background(), &stringSlice, false) if diags.HasError() { @@ -488,21 +488,21 @@ func TestListElementsAs_attributeValueSlice(t *testing.T) { } } -func TestListToTerraformValue(t *testing.T) { +func TestListValueToTerraformValue(t *testing.T) { t.Parallel() type testCase struct { - input List + input ListValue expectation tftypes.Value expectedErr string } tests := map[string]testCase{ "known": { - input: ListValueMust( - StringType, + input: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expectation: tftypes.NewValue(tftypes.List{ElementType: tftypes.String}, []tftypes.Value{ @@ -511,11 +511,11 @@ func TestListToTerraformValue(t *testing.T) { }), }, "known-partial-unknown": { - input: ListValueMust( - StringType, + input: NewListValueMust( + StringType{}, []attr.Value{ - StringUnknown(), - StringValue("hello, world"), + NewStringUnknown(), + NewStringValue("hello, world"), }, ), expectation: tftypes.NewValue(tftypes.List{ElementType: tftypes.String}, []tftypes.Value{ @@ -524,11 +524,11 @@ func TestListToTerraformValue(t *testing.T) { }), }, "known-partial-null": { - input: ListValueMust( - StringType, + input: NewListValueMust( + StringType{}, []attr.Value{ - StringNull(), - StringValue("hello, world"), + NewStringNull(), + NewStringValue("hello, world"), }, ), expectation: tftypes.NewValue(tftypes.List{ElementType: tftypes.String}, []tftypes.Value{ @@ -537,11 +537,11 @@ func TestListToTerraformValue(t *testing.T) { }), }, "unknown": { - input: ListUnknown(StringType), + input: NewListUnknown(StringType{}), expectation: tftypes.NewValue(tftypes.List{ElementType: tftypes.String}, tftypes.UnknownValue), }, "null": { - input: ListNull(StringType), + input: NewListNull(StringType{}), expectation: tftypes.NewValue(tftypes.List{ElementType: tftypes.String}, nil), }, } @@ -576,23 +576,23 @@ func TestListToTerraformValue(t *testing.T) { } } -func TestListElements(t *testing.T) { +func TestListValueElements(t *testing.T) { t.Parallel() testCases := map[string]struct { - input List + input ListValue expected []attr.Value }{ "known": { - input: ListValueMust(StringType, []attr.Value{StringValue("test")}), - expected: []attr.Value{StringValue("test")}, + input: NewListValueMust(StringType{}, []attr.Value{NewStringValue("test")}), + expected: []attr.Value{NewStringValue("test")}, }, "null": { - input: ListNull(StringType), + input: NewListNull(StringType{}), expected: nil, }, "unknown": { - input: ListUnknown(StringType), + input: NewListUnknown(StringType{}), expected: nil, }, } @@ -612,24 +612,24 @@ func TestListElements(t *testing.T) { } } -func TestListElementType(t *testing.T) { +func TestListValueElementType(t *testing.T) { t.Parallel() testCases := map[string]struct { - input List + input ListValue expected attr.Type }{ "known": { - input: ListValueMust(StringType, []attr.Value{StringValue("test")}), - expected: StringType, + input: NewListValueMust(StringType{}, []attr.Value{NewStringValue("test")}), + expected: StringType{}, }, "null": { - input: ListNull(StringType), - expected: StringType, + input: NewListNull(StringType{}), + expected: StringType{}, }, "unknown": { - input: ListUnknown(StringType), - expected: StringType, + input: NewListUnknown(StringType{}), + expected: StringType{}, }, } @@ -648,163 +648,163 @@ func TestListElementType(t *testing.T) { } } -func TestListEqual(t *testing.T) { +func TestListValueEqual(t *testing.T) { t.Parallel() type testCase struct { - receiver List + receiver ListValue input attr.Value expected bool } tests := map[string]testCase{ "known-known": { - receiver: ListValueMust( - StringType, + receiver: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: ListValueMust( - StringType, + input: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expected: true, }, "known-known-diff-value": { - receiver: ListValueMust( - StringType, + receiver: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: ListValueMust( - StringType, + input: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("goodnight"), - StringValue("moon"), + NewStringValue("goodnight"), + NewStringValue("moon"), }, ), expected: false, }, "known-known-diff-length": { - receiver: ListValueMust( - StringType, + receiver: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: ListValueMust( - StringType, + input: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), - StringValue("extra"), + NewStringValue("hello"), + NewStringValue("world"), + NewStringValue("extra"), }, ), expected: false, }, "known-known-diff-type": { - receiver: ListValueMust( - StringType, + receiver: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: SetValueMust( - BoolType, + input: NewSetValueMust( + BoolType{}, []attr.Value{ - BoolValue(false), - BoolValue(true), + NewBoolValue(false), + NewBoolValue(true), }, ), expected: false, }, "known-known-diff-unknown": { - receiver: ListValueMust( - StringType, + receiver: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringUnknown(), + NewStringValue("hello"), + NewStringUnknown(), }, ), - input: ListValueMust( - StringType, + input: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expected: false, }, "known-known-diff-null": { - receiver: ListValueMust( - StringType, + receiver: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringNull(), + NewStringValue("hello"), + NewStringNull(), }, ), - input: ListValueMust( - StringType, + input: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expected: false, }, "known-unknown": { - receiver: ListValueMust( - StringType, + receiver: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: ListUnknown(StringType), + input: NewListUnknown(StringType{}), expected: false, }, "known-null": { - receiver: ListValueMust( - StringType, + receiver: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: ListNull(StringType), + input: NewListNull(StringType{}), expected: false, }, "known-diff-type": { - receiver: ListValueMust( - StringType, + receiver: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expected: false, }, "known-nil": { - receiver: ListValueMust( - StringType, + receiver: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), input: nil, @@ -824,23 +824,23 @@ func TestListEqual(t *testing.T) { } } -func TestListIsNull(t *testing.T) { +func TestListValueIsNull(t *testing.T) { t.Parallel() testCases := map[string]struct { - input List + input ListValue expected bool }{ "known": { - input: ListValueMust(StringType, []attr.Value{StringValue("test")}), + input: NewListValueMust(StringType{}, []attr.Value{NewStringValue("test")}), expected: false, }, "null": { - input: ListNull(StringType), + input: NewListNull(StringType{}), expected: true, }, "unknown": { - input: ListUnknown(StringType), + input: NewListUnknown(StringType{}), expected: false, }, } @@ -860,23 +860,23 @@ func TestListIsNull(t *testing.T) { } } -func TestListIsUnknown(t *testing.T) { +func TestListValueIsUnknown(t *testing.T) { t.Parallel() testCases := map[string]struct { - input List + input ListValue expected bool }{ "known": { - input: ListValueMust(StringType, []attr.Value{StringValue("test")}), + input: NewListValueMust(StringType{}, []attr.Value{NewStringValue("test")}), expected: false, }, "null": { - input: ListNull(StringType), + input: NewListNull(StringType{}), expected: false, }, "unknown": { - input: ListUnknown(StringType), + input: NewListUnknown(StringType{}), expected: true, }, } @@ -896,42 +896,42 @@ func TestListIsUnknown(t *testing.T) { } } -func TestListString(t *testing.T) { +func TestListValueString(t *testing.T) { t.Parallel() type testCase struct { - input List + input ListValue expectation string } tests := map[string]testCase{ "known": { - input: ListValueMust( - StringType, + input: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expectation: `["hello","world"]`, }, "known-list-of-lists": { - input: ListValueMust( + input: NewListValueMust( ListType{ - ElemType: StringType, + ElemType: StringType{}, }, []attr.Value{ - ListValueMust( - StringType, + NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - ListValueMust( - StringType, + NewListValueMust( + StringType{}, []attr.Value{ - StringValue("foo"), - StringValue("bar"), + NewStringValue("foo"), + NewStringValue("bar"), }, ), }, @@ -939,15 +939,15 @@ func TestListString(t *testing.T) { expectation: `[["hello","world"],["foo","bar"]]`, }, "unknown": { - input: ListUnknown(StringType), + input: NewListUnknown(StringType{}), expectation: "", }, "null": { - input: ListNull(StringType), + input: NewListNull(StringType{}), expectation: "", }, "zero-value": { - input: List{}, + input: ListValue{}, expectation: "", }, } @@ -965,59 +965,59 @@ func TestListString(t *testing.T) { } } -func TestListType(t *testing.T) { +func TestListValueType(t *testing.T) { t.Parallel() type testCase struct { - input List + input ListValue expectation attr.Type } tests := map[string]testCase{ "known": { - input: ListValueMust( - StringType, + input: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - expectation: ListType{ElemType: StringType}, + expectation: ListType{ElemType: StringType{}}, }, "known-list-of-lists": { - input: ListValueMust( + input: NewListValueMust( ListType{ - ElemType: StringType, + ElemType: StringType{}, }, []attr.Value{ - ListValueMust( - StringType, + NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - ListValueMust( - StringType, + NewListValueMust( + StringType{}, []attr.Value{ - StringValue("foo"), - StringValue("bar"), + NewStringValue("foo"), + NewStringValue("bar"), }, ), }, ), expectation: ListType{ ElemType: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }, }, "unknown": { - input: ListUnknown(StringType), - expectation: ListType{ElemType: StringType}, + input: NewListUnknown(StringType{}), + expectation: ListType{ElemType: StringType{}}, }, "null": { - input: ListNull(StringType), - expectation: ListType{ElemType: StringType}, + input: NewListNull(StringType{}), + expectation: ListType{ElemType: StringType{}}, }, } @@ -1045,7 +1045,7 @@ func TestListTypeValidate(t *testing.T) { }{ "wrong-value-type": { listType: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, tfValue: tftypes.NewValue(tftypes.Set{ ElementType: tftypes.String, @@ -1064,7 +1064,7 @@ func TestListTypeValidate(t *testing.T) { }, "no-validation": { listType: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, tfValue: tftypes.NewValue(tftypes.List{ ElementType: tftypes.String, diff --git a/types/map.go b/types/basetypes/map.go similarity index 82% rename from types/map.go rename to types/basetypes/map.go index 990407462..6171633b7 100644 --- a/types/map.go +++ b/types/basetypes/map.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -17,7 +17,7 @@ import ( var ( _ MapTypable = MapType{} - _ MapValuable = &Map{} + _ MapValuable = &MapValue{} ) // MapTypable extends attr.Type for map types. @@ -26,7 +26,7 @@ type MapTypable interface { attr.Type // ValueFromMap should convert the Map to a MapValuable type. - ValueFromMap(context.Context, Map) (MapValuable, diag.Diagnostics) + ValueFromMap(context.Context, MapValue) (MapValuable, diag.Diagnostics) } // MapValuable extends attr.Value for map value types. @@ -35,7 +35,7 @@ type MapValuable interface { attr.Value // ToMapValue should convert the value type to a Map. - ToMapValue(ctx context.Context) (Map, diag.Diagnostics) + ToMapValue(ctx context.Context) (MapValue, diag.Diagnostics) } // MapType is an AttributeType representing a map of values. All values must @@ -72,19 +72,19 @@ func (m MapType) TerraformType(ctx context.Context) tftypes.Type { // provider to consume the data with. func (m MapType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { if in.Type() == nil { - return MapNull(m.ElemType), nil + return NewMapNull(m.ElemType), nil } if !in.Type().Is(tftypes.Map{}) { - return nil, fmt.Errorf("can't use %s as value of Map, can only use tftypes.Map values", in.String()) + return nil, fmt.Errorf("can't use %s as value of MapValue, can only use tftypes.Map values", in.String()) } if !in.Type().Equal(tftypes.Map{ElementType: m.ElemType.TerraformType(ctx)}) { return nil, fmt.Errorf("can't use %s as value of Map with ElementType %T, can only use %s values", in.String(), m.ElemType, m.ElemType.TerraformType(ctx).String()) } if !in.IsKnown() { - return MapUnknown(m.ElemType), nil + return NewMapUnknown(m.ElemType), nil } if in.IsNull() { - return MapNull(m.ElemType), nil + return NewMapNull(m.ElemType), nil } val := map[string]tftypes.Value{} err := in.As(&val) @@ -101,7 +101,7 @@ func (m MapType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr } // ValueFromTerraform above on each element should make this safe. // Otherwise, this will need to do some Diagnostics to error conversion. - return MapValueMust(m.ElemType, elems), nil + return NewMapValueMust(m.ElemType, elems), nil } // Equal returns true if `o` is also a MapType and has the same ElemType. @@ -182,37 +182,37 @@ func (m MapType) Validate(ctx context.Context, in tftypes.Value, path path.Path) // ValueType returns the Value type. func (m MapType) ValueType(_ context.Context) attr.Value { - return Map{ + return MapValue{ elementType: m.ElemType, } } // ValueFromMap returns a MapValuable type given a Map. -func (m MapType) ValueFromMap(_ context.Context, ma Map) (MapValuable, diag.Diagnostics) { +func (m MapType) ValueFromMap(_ context.Context, ma MapValue) (MapValuable, diag.Diagnostics) { return ma, nil } -// MapNull creates a Map with a null value. Determine whether the value is +// NewMapNull creates a Map with a null value. Determine whether the value is // null via the Map type IsNull method. -func MapNull(elementType attr.Type) Map { - return Map{ +func NewMapNull(elementType attr.Type) MapValue { + return MapValue{ elementType: elementType, state: attr.ValueStateNull, } } -// MapUnknown creates a Map with an unknown value. Determine whether the +// NewMapUnknown creates a Map with an unknown value. Determine whether the // value is unknown via the Map type IsUnknown method. -func MapUnknown(elementType attr.Type) Map { - return Map{ +func NewMapUnknown(elementType attr.Type) MapValue { + return MapValue{ elementType: elementType, state: attr.ValueStateUnknown, } } -// MapValue creates a Map with a known value. Access the value via the Map +// NewMapValue creates a Map with a known value. Access the value via the Map // type Elements or ElementsAs methods. -func MapValue(elementType attr.Type, elements map[string]attr.Value) (Map, diag.Diagnostics) { +func NewMapValue(elementType attr.Type, elements map[string]attr.Value) (MapValue, diag.Diagnostics) { var diags diag.Diagnostics // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 @@ -232,21 +232,21 @@ func MapValue(elementType attr.Type, elements map[string]attr.Value) (Map, diag. } if diags.HasError() { - return MapUnknown(elementType), diags + return NewMapUnknown(elementType), diags } - return Map{ + return MapValue{ elementType: elementType, elements: elements, state: attr.ValueStateKnown, }, nil } -// MapValueFrom creates a Map with a known value, using reflection rules. +// NewMapValueFrom creates a Map with a known value, using reflection rules. // The elements must be a map of string keys to values which can convert into // the given element type. Access the value via the Map type Elements or // ElementsAs methods. -func MapValueFrom(ctx context.Context, elementType attr.Type, elements any) (Map, diag.Diagnostics) { +func NewMapValueFrom(ctx context.Context, elementType attr.Type, elements any) (MapValue, diag.Diagnostics) { attrValue, diags := reflect.FromValue( ctx, MapType{ElemType: elementType}, @@ -255,10 +255,10 @@ func MapValueFrom(ctx context.Context, elementType attr.Type, elements any) (Map ) if diags.HasError() { - return MapUnknown(elementType), diags + return NewMapUnknown(elementType), diags } - m, ok := attrValue.(Map) + m, ok := attrValue.(MapValue) // This should not happen, but ensure there is an error if it does. if !ok { @@ -272,15 +272,15 @@ func MapValueFrom(ctx context.Context, elementType attr.Type, elements any) (Map return m, diags } -// MapValueMust creates a Map with a known value, converting any diagnostics +// NewMapValueMust creates a Map with a known value, converting any diagnostics // into a panic at runtime. Access the value via the Map // type Elements or ElementsAs methods. // // This creation function is only recommended to create Map values which will // not potentially effect practitioners, such as testing, or exhaustively // tested provider logic. -func MapValueMust(elementType attr.Type, elements map[string]attr.Value) Map { - m, diags := MapValue(elementType, elements) +func NewMapValueMust(elementType attr.Type, elements map[string]attr.Value) MapValue { + m, diags := NewMapValue(elementType, elements) if diags.HasError() { // This could potentially be added to the diag package. @@ -300,9 +300,9 @@ func MapValueMust(elementType attr.Type, elements map[string]attr.Value) Map { return m } -// Map represents a mapping of string keys to attr.Value values of a single +// MapValue represents a mapping of string keys to attr.Value values of a single // type. -type Map struct { +type MapValue struct { // elements is the mapping of known values in the Map. elements map[string]attr.Value @@ -316,13 +316,13 @@ type Map struct { // Elements returns the mapping of elements for the Map. Returns nil if the // Map is null or unknown. -func (m Map) Elements() map[string]attr.Value { +func (m MapValue) Elements() map[string]attr.Value { return m.elements } -// ElementsAs populates `target` with the elements of the Map, throwing an +// ElementsAs populates `target` with the elements of the MapValue, throwing an // error if the elements cannot be stored in `target`. -func (m Map) ElementsAs(ctx context.Context, target interface{}, allowUnhandled bool) diag.Diagnostics { +func (m MapValue) ElementsAs(ctx context.Context, target interface{}, allowUnhandled bool) diag.Diagnostics { // we need a tftypes.Value for this Map to be able to use it with our // reflection code val, err := m.ToTerraformValue(ctx) @@ -343,17 +343,17 @@ func (m Map) ElementsAs(ctx context.Context, target interface{}, allowUnhandled } // ElementType returns the element type for the Map. -func (m Map) ElementType(_ context.Context) attr.Type { +func (m MapValue) ElementType(_ context.Context) attr.Type { return m.elementType } // Type returns a MapType with the same element type as `m`. -func (m Map) Type(ctx context.Context) attr.Type { +func (m MapValue) Type(ctx context.Context) attr.Type { return MapType{ElemType: m.ElementType(ctx)} } // ToTerraformValue returns the data contained in the Map as a tftypes.Value. -func (m Map) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { +func (m MapValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { mapType := tftypes.Map{ElementType: m.ElementType(ctx).TerraformType(ctx)} switch m.state { @@ -386,8 +386,8 @@ func (m Map) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { // Equal returns true if the Map is considered semantically equal // (same type and same value) to the attr.Value passed as an argument. -func (m Map) Equal(o attr.Value) bool { - other, ok := o.(Map) +func (m MapValue) Equal(o attr.Value) bool { + other, ok := o.(MapValue) if !ok { return false @@ -421,21 +421,21 @@ func (m Map) Equal(o attr.Value) bool { } // IsNull returns true if the Map represents a null value. -func (m Map) IsNull() bool { +func (m MapValue) IsNull() bool { return m.state == attr.ValueStateNull } // IsUnknown returns true if the Map represents a currently unknown value. // Returns false if the Map has a known number of elements, even if all are // unknown values. -func (m Map) IsUnknown() bool { +func (m MapValue) IsUnknown() bool { return m.state == attr.ValueStateUnknown } // String returns a human-readable representation of the Map value. // The string returned here is not protected by any compatibility guarantees, // and is intended for logging and error reporting. -func (m Map) String() string { +func (m MapValue) String() string { if m.IsUnknown() { return attr.UnknownValueString } @@ -466,6 +466,6 @@ func (m Map) String() string { } // ToMapValue returns the Map. -func (m Map) ToMapValue(context.Context) (Map, diag.Diagnostics) { +func (m MapValue) ToMapValue(context.Context) (MapValue, diag.Diagnostics) { return m, nil } diff --git a/types/map_test.go b/types/basetypes/map_test.go similarity index 65% rename from types/map_test.go rename to types/basetypes/map_test.go index 4c2df2810..0de66af2e 100644 --- a/types/map_test.go +++ b/types/basetypes/map_test.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -22,7 +22,7 @@ func TestMapTypeTerraformType(t *testing.T) { tests := map[string]testCase{ "map-of-strings": { input: MapType{ - ElemType: StringType, + ElemType: StringType{}, }, expected: tftypes.Map{ ElementType: tftypes.String, @@ -31,7 +31,7 @@ func TestMapTypeTerraformType(t *testing.T) { "map-of-map-of-strings": { input: MapType{ ElemType: MapType{ - ElemType: StringType, + ElemType: StringType{}, }, }, expected: tftypes.Map{ @@ -44,7 +44,7 @@ func TestMapTypeTerraformType(t *testing.T) { input: MapType{ ElemType: MapType{ ElemType: MapType{ - ElemType: StringType, + ElemType: StringType{}, }, }, }, @@ -80,7 +80,7 @@ func TestMapTypeValueFromTerraform(t *testing.T) { tests := map[string]testCase{ "basic-map": { receiver: MapType{ - ElemType: NumberType, + ElemType: NumberType{}, }, input: tftypes.NewValue(tftypes.Map{ ElementType: tftypes.Number, @@ -89,46 +89,46 @@ func TestMapTypeValueFromTerraform(t *testing.T) { "two": tftypes.NewValue(tftypes.Number, 2), "three": tftypes.NewValue(tftypes.Number, 3), }), - expected: MapValueMust( - NumberType, + expected: NewMapValueMust( + NumberType{}, map[string]attr.Value{ - "one": NumberValue(big.NewFloat(1)), - "two": NumberValue(big.NewFloat(2)), - "three": NumberValue(big.NewFloat(3)), + "one": NewNumberValue(big.NewFloat(1)), + "two": NewNumberValue(big.NewFloat(2)), + "three": NewNumberValue(big.NewFloat(3)), }, ), }, "wrong-type": { receiver: MapType{ - ElemType: NumberType, + ElemType: NumberType{}, }, input: tftypes.NewValue(tftypes.String, "wrong"), - expectedErr: `can't use tftypes.String<"wrong"> as value of Map, can only use tftypes.Map values`, + expectedErr: `can't use tftypes.String<"wrong"> as value of MapValue, can only use tftypes.Map values`, }, "nil-type": { receiver: MapType{ - ElemType: NumberType, + ElemType: NumberType{}, }, input: tftypes.NewValue(nil, nil), - expected: MapNull(NumberType), + expected: NewMapNull(NumberType{}), }, "unknown": { receiver: MapType{ - ElemType: NumberType, + ElemType: NumberType{}, }, input: tftypes.NewValue(tftypes.Map{ ElementType: tftypes.Number, }, tftypes.UnknownValue), - expected: MapUnknown(NumberType), + expected: NewMapUnknown(NumberType{}), }, "null": { receiver: MapType{ - ElemType: NumberType, + ElemType: NumberType{}, }, input: tftypes.NewValue(tftypes.Map{ ElementType: tftypes.Number, }, nil), - expected: MapNull(NumberType), + expected: NewMapNull(NumberType{}), }, } @@ -177,12 +177,12 @@ func TestMapTypeEqual(t *testing.T) { "equal": { receiver: MapType{ ElemType: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }, input: MapType{ ElemType: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }, expected: true, @@ -190,26 +190,26 @@ func TestMapTypeEqual(t *testing.T) { "diff": { receiver: MapType{ ElemType: ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }, input: MapType{ ElemType: ListType{ - ElemType: NumberType, + ElemType: NumberType{}, }, }, expected: false, }, "wrongType": { receiver: MapType{ - ElemType: StringType, + ElemType: StringType{}, }, - input: NumberType, + input: NumberType{}, expected: false, }, "nil": { receiver: MapType{ - ElemType: StringType, + ElemType: StringType{}, }, input: nil, expected: false, @@ -235,51 +235,51 @@ func TestMapTypeEqual(t *testing.T) { } } -func TestMapValue(t *testing.T) { +func TestNewMapValue(t *testing.T) { t.Parallel() testCases := map[string]struct { elementType attr.Type elements map[string]attr.Value - expected Map + expected MapValue expectedDiags diag.Diagnostics }{ "valid-no-elements": { - elementType: StringType, + elementType: StringType{}, elements: map[string]attr.Value{}, - expected: MapValueMust(StringType, map[string]attr.Value{}), + expected: NewMapValueMust(StringType{}, map[string]attr.Value{}), }, "valid-elements": { - elementType: StringType, + elementType: StringType{}, elements: map[string]attr.Value{ - "null": StringNull(), - "unknown": StringUnknown(), - "known": StringValue("test"), + "null": NewStringNull(), + "unknown": NewStringUnknown(), + "known": NewStringValue("test"), }, - expected: MapValueMust( - StringType, + expected: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "null": StringNull(), - "unknown": StringUnknown(), - "known": StringValue("test"), + "null": NewStringNull(), + "unknown": NewStringUnknown(), + "known": NewStringValue("test"), }, ), }, "invalid-element-type": { - elementType: StringType, + elementType: StringType{}, elements: map[string]attr.Value{ - "string": StringValue("test"), - "bool": BoolValue(true), + "string": NewStringValue("test"), + "bool": NewBoolValue(true), }, - expected: MapUnknown(StringType), + expected: NewMapUnknown(StringType{}), expectedDiags: diag.Diagnostics{ diag.NewErrorDiagnostic( "Invalid Map Element Type", "While creating a Map value, an invalid element was detected. "+ "A Map must use the single, given element type. "+ "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ - "Map Element Type: types.StringType\n"+ - "Map Key (bool) Element Type: types.BoolType", + "Map Element Type: basetypes.StringType\n"+ + "Map Key (bool) Element Type: basetypes.BoolType", ), }, }, @@ -291,7 +291,7 @@ func TestMapValue(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - got, diags := MapValue(testCase.elementType, testCase.elements) + got, diags := NewMapValue(testCase.elementType, testCase.elements) if diff := cmp.Diff(got, testCase.expected); diff != "" { t.Errorf("unexpected difference: %s", diff) @@ -304,81 +304,81 @@ func TestMapValue(t *testing.T) { } } -func TestMapValueFrom(t *testing.T) { +func TestNewMapValueFrom(t *testing.T) { t.Parallel() testCases := map[string]struct { elementType attr.Type elements any - expected Map + expected MapValue expectedDiags diag.Diagnostics }{ - "valid-StringType-map[string]attr.Value-empty": { - elementType: StringType, + "valid-StringType{}-map[string]attr.Value-empty": { + elementType: StringType{}, elements: map[string]attr.Value{}, - expected: MapValueMust( - StringType, + expected: NewMapValueMust( + StringType{}, map[string]attr.Value{}, ), }, - "valid-StringType-map[string]types.String-empty": { - elementType: StringType, - elements: map[string]String{}, - expected: MapValueMust( - StringType, + "valid-StringType{}-map[string]types.String-empty": { + elementType: StringType{}, + elements: map[string]StringValue{}, + expected: NewMapValueMust( + StringType{}, map[string]attr.Value{}, ), }, - "valid-StringType-map[string]types.String": { - elementType: StringType, - elements: map[string]String{ - "key1": StringNull(), - "key2": StringUnknown(), - "key3": StringValue("test"), + "valid-StringType{}-map[string]types.String": { + elementType: StringType{}, + elements: map[string]StringValue{ + "key1": NewStringNull(), + "key2": NewStringUnknown(), + "key3": NewStringValue("test"), }, - expected: MapValueMust( - StringType, + expected: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringNull(), - "key2": StringUnknown(), - "key3": StringValue("test"), + "key1": NewStringNull(), + "key2": NewStringUnknown(), + "key3": NewStringValue("test"), }, ), }, - "valid-StringType-map[string]*string": { - elementType: StringType, + "valid-StringType{}-map[string]*string": { + elementType: StringType{}, elements: map[string]*string{ "key1": nil, "key2": pointer("test1"), "key3": pointer("test2"), }, - expected: MapValueMust( - StringType, + expected: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringNull(), - "key2": StringValue("test1"), - "key3": StringValue("test2"), + "key1": NewStringNull(), + "key2": NewStringValue("test1"), + "key3": NewStringValue("test2"), }, ), }, - "valid-StringType-map[string]string": { - elementType: StringType, + "valid-StringType{}-map[string]string": { + elementType: StringType{}, elements: map[string]string{ "key1": "test1", "key2": "test2", }, - expected: MapValueMust( - StringType, + expected: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("test1"), - "key2": StringValue("test2"), + "key1": NewStringValue("test1"), + "key2": NewStringValue("test2"), }, ), }, "invalid-not-map": { - elementType: StringType, + elementType: StringType{}, elements: "oops", - expected: MapUnknown(StringType), + expected: NewMapUnknown(StringType{}), expectedDiags: diag.Diagnostics{ diag.NewAttributeErrorDiagnostic( path.Empty(), @@ -389,9 +389,9 @@ func TestMapValueFrom(t *testing.T) { }, }, "invalid-type": { - elementType: StringType, + elementType: StringType{}, elements: map[string]bool{"key1": true}, - expected: MapUnknown(StringType), + expected: NewMapUnknown(StringType{}), expectedDiags: diag.Diagnostics{ diag.NewAttributeErrorDiagnostic( path.Empty().AtMapKey("key1"), @@ -409,7 +409,7 @@ func TestMapValueFrom(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - got, diags := MapValueFrom(context.Background(), testCase.elementType, testCase.elements) + got, diags := NewMapValueFrom(context.Background(), testCase.elementType, testCase.elements) if diff := cmp.Diff(got, testCase.expected); diff != "" { t.Errorf("unexpected difference: %s", diff) @@ -431,11 +431,11 @@ func TestMapElementsAs_mapStringString(t *testing.T) { "w": "world", } - diags := MapValueMust( - StringType, + diags := NewMapValueMust( + StringType{}, map[string]attr.Value{ - "h": StringValue("hello"), - "w": StringValue("world"), + "h": NewStringValue("hello"), + "w": NewStringValue("world"), }, ).ElementsAs(context.Background(), &stringSlice, false) if diags.HasError() { @@ -449,17 +449,17 @@ func TestMapElementsAs_mapStringString(t *testing.T) { func TestMapElementsAs_mapStringAttributeValue(t *testing.T) { t.Parallel() - var stringSlice map[string]String - expected := map[string]String{ - "h": StringValue("hello"), - "w": StringValue("world"), + var stringSlice map[string]StringValue + expected := map[string]StringValue{ + "h": NewStringValue("hello"), + "w": NewStringValue("world"), } - diags := MapValueMust( - StringType, + diags := NewMapValueMust( + StringType{}, map[string]attr.Value{ - "h": StringValue("hello"), - "w": StringValue("world"), + "h": NewStringValue("hello"), + "w": NewStringValue("world"), }, ).ElementsAs(context.Background(), &stringSlice, false) if diags.HasError() { @@ -470,21 +470,21 @@ func TestMapElementsAs_mapStringAttributeValue(t *testing.T) { } } -func TestMapToTerraformValue(t *testing.T) { +func TestMapValueToTerraformValue(t *testing.T) { t.Parallel() type testCase struct { - input Map + input MapValue expectation tftypes.Value expectedErr string } tests := map[string]testCase{ "known": { - input: MapValueMust( - StringType, + input: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), expectation: tftypes.NewValue(tftypes.Map{ElementType: tftypes.String}, map[string]tftypes.Value{ @@ -493,11 +493,11 @@ func TestMapToTerraformValue(t *testing.T) { }), }, "known-partial-unknown": { - input: MapValueMust( - StringType, + input: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringUnknown(), - "key2": StringValue("hello, world"), + "key1": NewStringUnknown(), + "key2": NewStringValue("hello, world"), }, ), expectation: tftypes.NewValue(tftypes.Map{ElementType: tftypes.String}, map[string]tftypes.Value{ @@ -506,11 +506,11 @@ func TestMapToTerraformValue(t *testing.T) { }), }, "known-partial-null": { - input: MapValueMust( - StringType, + input: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringNull(), - "key2": StringValue("hello, world"), + "key1": NewStringNull(), + "key2": NewStringValue("hello, world"), }, ), expectation: tftypes.NewValue(tftypes.Map{ElementType: tftypes.String}, map[string]tftypes.Value{ @@ -519,11 +519,11 @@ func TestMapToTerraformValue(t *testing.T) { }), }, "unknown": { - input: MapUnknown(StringType), + input: NewMapUnknown(StringType{}), expectation: tftypes.NewValue(tftypes.Map{ElementType: tftypes.String}, tftypes.UnknownValue), }, "null": { - input: MapNull(StringType), + input: NewMapNull(StringType{}), expectation: tftypes.NewValue(tftypes.Map{ElementType: tftypes.String}, nil), }, } @@ -558,23 +558,23 @@ func TestMapToTerraformValue(t *testing.T) { } } -func TestMapElements(t *testing.T) { +func TestMapValueElements(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Map + input MapValue expected map[string]attr.Value }{ "known": { - input: MapValueMust(StringType, map[string]attr.Value{"test-key": StringValue("test-value")}), - expected: map[string]attr.Value{"test-key": StringValue("test-value")}, + input: NewMapValueMust(StringType{}, map[string]attr.Value{"test-key": NewStringValue("test-value")}), + expected: map[string]attr.Value{"test-key": NewStringValue("test-value")}, }, "null": { - input: MapNull(StringType), + input: NewMapNull(StringType{}), expected: nil, }, "unknown": { - input: MapUnknown(StringType), + input: NewMapUnknown(StringType{}), expected: nil, }, } @@ -594,24 +594,24 @@ func TestMapElements(t *testing.T) { } } -func TestMapElementType(t *testing.T) { +func TestMapValueElementType(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Map + input MapValue expected attr.Type }{ "known": { - input: MapValueMust(StringType, map[string]attr.Value{"test-key": StringValue("test-value")}), - expected: StringType, + input: NewMapValueMust(StringType{}, map[string]attr.Value{"test-key": NewStringValue("test-value")}), + expected: StringType{}, }, "null": { - input: MapNull(StringType), - expected: StringType, + input: NewMapNull(StringType{}), + expected: StringType{}, }, "unknown": { - input: MapUnknown(StringType), - expected: StringType, + input: NewMapUnknown(StringType{}), + expected: StringType{}, }, } @@ -630,163 +630,163 @@ func TestMapElementType(t *testing.T) { } } -func TestMapEqual(t *testing.T) { +func TestMapValueEqual(t *testing.T) { t.Parallel() type testCase struct { - receiver Map + receiver MapValue input attr.Value expected bool } tests := map[string]testCase{ "known-known": { - receiver: MapValueMust( - StringType, + receiver: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), - input: MapValueMust( - StringType, + input: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), expected: true, }, "known-known-diff-value": { - receiver: MapValueMust( - StringType, + receiver: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), - input: MapValueMust( - StringType, + input: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("goodnight"), - "key2": StringValue("moon"), + "key1": NewStringValue("goodnight"), + "key2": NewStringValue("moon"), }, ), expected: false, }, "known-known-diff-length": { - receiver: MapValueMust( - StringType, + receiver: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), - input: MapValueMust( - StringType, + input: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), - "key3": StringValue("extra"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), + "key3": NewStringValue("extra"), }, ), expected: false, }, "known-known-diff-type": { - receiver: MapValueMust( - StringType, + receiver: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), - input: SetValueMust( - BoolType, + input: NewSetValueMust( + BoolType{}, []attr.Value{ - BoolValue(false), - BoolValue(true), + NewBoolValue(false), + NewBoolValue(true), }, ), expected: false, }, "known-known-diff-unknown": { - receiver: MapValueMust( - StringType, + receiver: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringUnknown(), + "key1": NewStringValue("hello"), + "key2": NewStringUnknown(), }, ), - input: MapValueMust( - StringType, + input: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), expected: false, }, "known-known-diff-null": { - receiver: MapValueMust( - StringType, + receiver: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringNull(), + "key1": NewStringValue("hello"), + "key2": NewStringNull(), }, ), - input: MapValueMust( - StringType, + input: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), expected: false, }, "known-unknown": { - receiver: MapValueMust( - StringType, + receiver: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), - input: MapUnknown(StringType), + input: NewMapUnknown(StringType{}), expected: false, }, "known-null": { - receiver: MapValueMust( - StringType, + receiver: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), - input: MapNull(StringType), + input: NewMapNull(StringType{}), expected: false, }, "known-diff-type": { - receiver: MapValueMust( - StringType, + receiver: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expected: false, }, "known-nil": { - receiver: MapValueMust( - StringType, + receiver: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), input: nil, @@ -806,23 +806,23 @@ func TestMapEqual(t *testing.T) { } } -func TestMapIsNull(t *testing.T) { +func TestMapValueIsNull(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Map + input MapValue expected bool }{ "known": { - input: MapValueMust(StringType, map[string]attr.Value{"test-key": StringValue("test-value")}), + input: NewMapValueMust(StringType{}, map[string]attr.Value{"test-key": NewStringValue("test-value")}), expected: false, }, "null": { - input: MapNull(StringType), + input: NewMapNull(StringType{}), expected: true, }, "unknown": { - input: MapUnknown(StringType), + input: NewMapUnknown(StringType{}), expected: false, }, } @@ -842,23 +842,23 @@ func TestMapIsNull(t *testing.T) { } } -func TestMapIsUnknown(t *testing.T) { +func TestMapValueIsUnknown(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Map + input MapValue expected bool }{ "known": { - input: MapValueMust(StringType, map[string]attr.Value{"test-key": StringValue("test-value")}), + input: NewMapValueMust(StringType{}, map[string]attr.Value{"test-key": NewStringValue("test-value")}), expected: false, }, "null": { - input: MapNull(StringType), + input: NewMapNull(StringType{}), expected: false, }, "unknown": { - input: MapUnknown(StringType), + input: NewMapUnknown(StringType{}), expected: true, }, } @@ -878,45 +878,45 @@ func TestMapIsUnknown(t *testing.T) { } } -func TestMapString(t *testing.T) { +func TestMapValueString(t *testing.T) { t.Parallel() type testCase struct { - input Map + input MapValue expectation string } tests := map[string]testCase{ "known": { - input: MapValueMust( - Int64Type, + input: NewMapValueMust( + Int64Type{}, map[string]attr.Value{ - "alpha": Int64Value(1234), - "beta": Int64Value(56789), - "gamma": Int64Value(9817), - "sigma": Int64Value(62534), + "alpha": NewInt64Value(1234), + "beta": NewInt64Value(56789), + "gamma": NewInt64Value(9817), + "sigma": NewInt64Value(62534), }, ), expectation: `{"alpha":1234,"beta":56789,"gamma":9817,"sigma":62534}`, }, "known-map-of-maps": { - input: MapValueMust( + input: NewMapValueMust( MapType{ - ElemType: StringType, + ElemType: StringType{}, }, map[string]attr.Value{ - "first": MapValueMust( - StringType, + "first": NewMapValueMust( + StringType{}, map[string]attr.Value{ - "alpha": StringValue("hello"), - "beta": StringValue("world"), - "gamma": StringValue("foo"), - "sigma": StringValue("bar"), + "alpha": NewStringValue("hello"), + "beta": NewStringValue("world"), + "gamma": NewStringValue("foo"), + "sigma": NewStringValue("bar"), }, ), - "second": MapValueMust( - StringType, + "second": NewMapValueMust( + StringType{}, map[string]attr.Value{ - "echo": StringValue("echo"), + "echo": NewStringValue("echo"), }, ), }, @@ -924,24 +924,24 @@ func TestMapString(t *testing.T) { expectation: `{"first":{"alpha":"hello","beta":"world","gamma":"foo","sigma":"bar"},"second":{"echo":"echo"}}`, }, "known-key-quotes": { - input: MapValueMust( - BoolType, + input: NewMapValueMust( + BoolType{}, map[string]attr.Value{ - `testing is "fun"`: BoolValue(true), + `testing is "fun"`: NewBoolValue(true), }, ), expectation: `{"testing is \"fun\"":true}`, }, "unknown": { - input: MapUnknown(StringType), + input: NewMapUnknown(StringType{}), expectation: "", }, "null": { - input: MapNull(StringType), + input: NewMapNull(StringType{}), expectation: "", }, "zero-value": { - input: Map{}, + input: MapValue{}, expectation: "", }, } @@ -959,59 +959,59 @@ func TestMapString(t *testing.T) { } } -func TestMapType(t *testing.T) { +func TestMapValueType(t *testing.T) { t.Parallel() type testCase struct { - input Map + input MapValue expectation attr.Type } tests := map[string]testCase{ "known": { - input: MapValueMust( - StringType, + input: NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), - expectation: MapType{ElemType: StringType}, + expectation: MapType{ElemType: StringType{}}, }, "known-map-of-maps": { - input: MapValueMust( + input: NewMapValueMust( MapType{ - ElemType: StringType, + ElemType: StringType{}, }, map[string]attr.Value{ - "key1": MapValueMust( - StringType, + "key1": NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("hello"), - "key2": StringValue("world"), + "key1": NewStringValue("hello"), + "key2": NewStringValue("world"), }, ), - "key2": MapValueMust( - StringType, + "key2": NewMapValueMust( + StringType{}, map[string]attr.Value{ - "key1": StringValue("foo"), - "key2": StringValue("bar"), + "key1": NewStringValue("foo"), + "key2": NewStringValue("bar"), }, ), }, ), expectation: MapType{ ElemType: MapType{ - ElemType: StringType, + ElemType: StringType{}, }, }, }, "unknown": { - input: MapUnknown(StringType), - expectation: MapType{ElemType: StringType}, + input: NewMapUnknown(StringType{}), + expectation: MapType{ElemType: StringType{}}, }, "null": { - input: MapNull(StringType), - expectation: MapType{ElemType: StringType}, + input: NewMapNull(StringType{}), + expectation: MapType{ElemType: StringType{}}, }, } @@ -1039,7 +1039,7 @@ func TestMapTypeValidate(t *testing.T) { }{ "wrong-value-type": { mapType: MapType{ - ElemType: StringType, + ElemType: StringType{}, }, tfValue: tftypes.NewValue(tftypes.List{ ElementType: tftypes.String, @@ -1058,7 +1058,7 @@ func TestMapTypeValidate(t *testing.T) { }, "no-validation": { mapType: MapType{ - ElemType: StringType, + ElemType: StringType{}, }, tfValue: tftypes.NewValue(tftypes.Map{ ElementType: tftypes.String, diff --git a/types/number.go b/types/basetypes/number.go similarity index 60% rename from types/number.go rename to types/basetypes/number.go index bfaba3a6d..a67905f8f 100644 --- a/types/number.go +++ b/types/basetypes/number.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -12,7 +12,7 @@ import ( ) var ( - _ NumberValuable = Number{} + _ NumberValuable = NumberValue{} ) // NumberValuable extends attr.Value for number value types. @@ -21,65 +21,41 @@ type NumberValuable interface { attr.Value // ToNumberValue should convert the value type to a Number. - ToNumberValue(ctx context.Context) (Number, diag.Diagnostics) + ToNumberValue(ctx context.Context) (NumberValue, diag.Diagnostics) } -// NumberNull creates a Number with a null value. Determine whether the value is +// NewNumberNull creates a Number with a null value. Determine whether the value is // null via the Number type IsNull method. -// -// Setting the deprecated Number type Null, Unknown, or Value fields after -// creating a Number with this function has no effect. -func NumberNull() Number { - return Number{ +func NewNumberNull() NumberValue { + return NumberValue{ state: attr.ValueStateNull, } } -// NumberUnknown creates a Number with an unknown value. Determine whether the +// NewNumberUnknown creates a Number with an unknown value. Determine whether the // value is unknown via the Number type IsUnknown method. -// -// Setting the deprecated Number type Null, Unknown, or Value fields after -// creating a Number with this function has no effect. -func NumberUnknown() Number { - return Number{ +func NewNumberUnknown() NumberValue { + return NumberValue{ state: attr.ValueStateUnknown, } } -// NumberValue creates a Number with a known value. Access the value via the Number +// NewNumberValue creates a Number with a known value. Access the value via the Number // type ValueBigFloat method. If the given value is nil, a null Number is created. -// -// Setting the deprecated Number type Null, Unknown, or Value fields after -// creating a Number with this function has no effect. -func NumberValue(value *big.Float) Number { +func NewNumberValue(value *big.Float) NumberValue { if value == nil { - return NumberNull() + return NewNumberNull() } - return Number{ + return NumberValue{ state: attr.ValueStateKnown, value: value, } } -func numberValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { - if !in.IsKnown() { - return NumberUnknown(), nil - } - if in.IsNull() { - return NumberNull(), nil - } - n := big.NewFloat(0) - err := in.As(&n) - if err != nil { - return nil, err - } - return NumberValue(n), nil -} - -// Number represents a number value, exposed as a *big.Float. Numbers can be +// NumberValue represents a number value, exposed as a *big.Float. Numbers can be // floats or integers. -type Number struct { +type NumberValue struct { // state represents whether the value is null, unknown, or known. The // zero-value is null. state attr.ValueState @@ -89,12 +65,12 @@ type Number struct { } // Type returns a NumberType. -func (n Number) Type(_ context.Context) attr.Type { - return NumberType +func (n NumberValue) Type(_ context.Context) attr.Type { + return NumberType{} } // ToTerraformValue returns the data contained in the Number as a tftypes.Value. -func (n Number) ToTerraformValue(_ context.Context) (tftypes.Value, error) { +func (n NumberValue) ToTerraformValue(_ context.Context) (tftypes.Value, error) { switch n.state { case attr.ValueStateKnown: if n.value == nil { @@ -116,8 +92,8 @@ func (n Number) ToTerraformValue(_ context.Context) (tftypes.Value, error) { } // Equal returns true if `other` is a Number and has the same value as `n`. -func (n Number) Equal(other attr.Value) bool { - o, ok := other.(Number) +func (n NumberValue) Equal(other attr.Value) bool { + o, ok := other.(NumberValue) if !ok { return false @@ -135,19 +111,19 @@ func (n Number) Equal(other attr.Value) bool { } // IsNull returns true if the Number represents a null value. -func (n Number) IsNull() bool { +func (n NumberValue) IsNull() bool { return n.state == attr.ValueStateNull } // IsUnknown returns true if the Number represents a currently unknown value. -func (n Number) IsUnknown() bool { +func (n NumberValue) IsUnknown() bool { return n.state == attr.ValueStateUnknown } // String returns a human-readable representation of the Number value. // The string returned here is not protected by any compatibility guarantees, // and is intended for logging and error reporting. -func (n Number) String() string { +func (n NumberValue) String() string { if n.IsUnknown() { return attr.UnknownValueString } @@ -161,11 +137,11 @@ func (n Number) String() string { // ValueBigFloat returns the known *big.Float value. If Number is null or unknown, returns // 0.0. -func (n Number) ValueBigFloat() *big.Float { +func (n NumberValue) ValueBigFloat() *big.Float { return n.value } // ToNumberValue returns Number. -func (n Number) ToNumberValue(context.Context) (Number, diag.Diagnostics) { +func (n NumberValue) ToNumberValue(context.Context) (NumberValue, diag.Diagnostics) { return n, nil } diff --git a/types/number_test.go b/types/basetypes/number_test.go similarity index 68% rename from types/number_test.go rename to types/basetypes/number_test.go index 6207f9d4c..2ddde3176 100644 --- a/types/number_test.go +++ b/types/basetypes/number_test.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -15,13 +15,9 @@ func numberComparer(i, j *big.Float) bool { return (i == nil && j == nil) || (i != nil && j != nil && i.Cmp(j) == 0) } -func TestNumberValueFromTerraform(t *testing.T) { +func TestNumberTypeValueFromTerraform(t *testing.T) { t.Parallel() - testNumberValueFromTerraform(t, true) -} - -func testNumberValueFromTerraform(t *testing.T, direct bool) { type testCase struct { input tftypes.Value expectation attr.Value @@ -30,15 +26,15 @@ func testNumberValueFromTerraform(t *testing.T, direct bool) { tests := map[string]testCase{ "value": { input: tftypes.NewValue(tftypes.Number, 123), - expectation: NumberValue(big.NewFloat(123)), + expectation: NewNumberValue(big.NewFloat(123)), }, "unknown": { input: tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), - expectation: NumberUnknown(), + expectation: NewNumberUnknown(), }, "null": { input: tftypes.NewValue(tftypes.Number, nil), - expectation: NumberNull(), + expectation: NewNumberNull(), }, "wrongType": { input: tftypes.NewValue(tftypes.String, "oops"), @@ -51,11 +47,7 @@ func testNumberValueFromTerraform(t *testing.T, direct bool) { t.Parallel() ctx := context.Background() - f := NumberType.ValueFromTerraform - if direct { - f = numberValueFromTerraform - } - got, err := f(ctx, test.input) + got, err := NumberType{}.ValueFromTerraform(ctx, test.input) if err != nil { if test.expectedErr == "" { t.Errorf("Unexpected error: %s", err) @@ -86,28 +78,28 @@ func testNumberValueFromTerraform(t *testing.T, direct bool) { } } -func TestNumberToTerraformValue(t *testing.T) { +func TestNumberValueToTerraformValue(t *testing.T) { t.Parallel() type testCase struct { - input Number + input NumberValue expectation tftypes.Value } tests := map[string]testCase{ "value": { - input: NumberValue(big.NewFloat(123)), + input: NewNumberValue(big.NewFloat(123)), expectation: tftypes.NewValue(tftypes.Number, big.NewFloat(123)), }, "known-nil": { - input: NumberValue(nil), + input: NewNumberValue(nil), expectation: tftypes.NewValue(tftypes.Number, nil), }, "unknown": { - input: NumberUnknown(), + input: NewNumberUnknown(), expectation: tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), }, "null": { - input: NumberNull(), + input: NewNumberNull(), expectation: tftypes.NewValue(tftypes.Number, nil), }, } @@ -129,107 +121,107 @@ func TestNumberToTerraformValue(t *testing.T) { } } -func TestNumberEqual(t *testing.T) { +func TestNumberValueEqual(t *testing.T) { t.Parallel() type testCase struct { - input Number + input NumberValue candidate attr.Value expectation bool } tests := map[string]testCase{ "known-known-same": { - input: NumberValue(big.NewFloat(123)), - candidate: NumberValue(big.NewFloat(123)), + input: NewNumberValue(big.NewFloat(123)), + candidate: NewNumberValue(big.NewFloat(123)), expectation: true, }, "known-known-diff": { - input: NumberValue(big.NewFloat(123)), - candidate: NumberValue(big.NewFloat(456)), + input: NewNumberValue(big.NewFloat(123)), + candidate: NewNumberValue(big.NewFloat(456)), expectation: false, }, "known-nil-known": { - input: NumberValue(nil), - candidate: NumberValue(big.NewFloat(456)), + input: NewNumberValue(nil), + candidate: NewNumberValue(big.NewFloat(456)), expectation: false, }, "known-nil-null": { - input: NumberValue(nil), - candidate: NumberNull(), + input: NewNumberValue(nil), + candidate: NewNumberNull(), expectation: true, }, "known-unknown": { - input: NumberValue(big.NewFloat(123)), - candidate: NumberUnknown(), + input: NewNumberValue(big.NewFloat(123)), + candidate: NewNumberUnknown(), expectation: false, }, "known-null": { - input: NumberValue(big.NewFloat(123)), - candidate: NumberNull(), + input: NewNumberValue(big.NewFloat(123)), + candidate: NewNumberNull(), expectation: false, }, "known-wrong-type": { - input: NumberValue(big.NewFloat(123)), - candidate: Float64Value(123), + input: NewNumberValue(big.NewFloat(123)), + candidate: NewFloat64Value(123), expectation: false, }, "known-nil": { - input: NumberValue(big.NewFloat(123)), + input: NewNumberValue(big.NewFloat(123)), candidate: nil, expectation: false, }, "unknown-known": { - input: NumberUnknown(), - candidate: NumberValue(big.NewFloat(123)), + input: NewNumberUnknown(), + candidate: NewNumberValue(big.NewFloat(123)), expectation: false, }, "unknown-unknown": { - input: NumberUnknown(), - candidate: NumberUnknown(), + input: NewNumberUnknown(), + candidate: NewNumberUnknown(), expectation: true, }, "unknown-null": { - input: NumberUnknown(), - candidate: NumberNull(), + input: NewNumberUnknown(), + candidate: NewNumberNull(), expectation: false, }, "unknown-wrong-type": { - input: NumberUnknown(), - candidate: Float64Unknown(), + input: NewNumberUnknown(), + candidate: NewFloat64Unknown(), expectation: false, }, "unknown-nil": { - input: NumberUnknown(), + input: NewNumberUnknown(), candidate: nil, expectation: false, }, "null-known": { - input: NumberNull(), - candidate: NumberValue(big.NewFloat(123)), + input: NewNumberNull(), + candidate: NewNumberValue(big.NewFloat(123)), expectation: false, }, "null-known-nil": { - input: NumberNull(), - candidate: NumberValue(nil), + input: NewNumberNull(), + candidate: NewNumberValue(nil), expectation: true, }, "null-unknown": { - input: NumberNull(), - candidate: NumberUnknown(), + input: NewNumberNull(), + candidate: NewNumberUnknown(), expectation: false, }, "null-null": { - input: NumberNull(), - candidate: NumberNull(), + input: NewNumberNull(), + candidate: NewNumberNull(), expectation: true, }, "null-wrong-type": { - input: NumberNull(), - candidate: Float64Null(), + input: NewNumberNull(), + candidate: NewFloat64Null(), expectation: false, }, "null-nil": { - input: NumberNull(), + input: NewNumberNull(), candidate: nil, expectation: false, }, @@ -247,23 +239,23 @@ func TestNumberEqual(t *testing.T) { } } -func TestNumberIsNull(t *testing.T) { +func TestNumberValueIsNull(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Number + input NumberValue expected bool }{ "known": { - input: NumberValue(big.NewFloat(2.4)), + input: NewNumberValue(big.NewFloat(2.4)), expected: false, }, "null": { - input: NumberNull(), + input: NewNumberNull(), expected: true, }, "unknown": { - input: NumberUnknown(), + input: NewNumberUnknown(), expected: false, }, } @@ -283,23 +275,23 @@ func TestNumberIsNull(t *testing.T) { } } -func TestNumberIsUnknown(t *testing.T) { +func TestNumberValueIsUnknown(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Number + input NumberValue expected bool }{ "known": { - input: NumberValue(big.NewFloat(2.4)), + input: NewNumberValue(big.NewFloat(2.4)), expected: false, }, "null": { - input: NumberNull(), + input: NewNumberNull(), expected: false, }, "unknown": { - input: NumberUnknown(), + input: NewNumberUnknown(), expected: true, }, } @@ -319,44 +311,44 @@ func TestNumberIsUnknown(t *testing.T) { } } -func TestNumberString(t *testing.T) { +func TestNumberValueString(t *testing.T) { t.Parallel() type testCase struct { - input Number + input NumberValue expectation string } tests := map[string]testCase{ "known-less-than-one": { - input: NumberValue(big.NewFloat(0.12340984302980000)), + input: NewNumberValue(big.NewFloat(0.12340984302980000)), expectation: "0.123409843", }, "known-more-than-one": { - input: NumberValue(big.NewFloat(92387938173219.327663)), + input: NewNumberValue(big.NewFloat(92387938173219.327663)), expectation: "9.238793817e+13", }, "known-negative-more-than-one": { - input: NumberValue(big.NewFloat(-0.12340984302980000)), + input: NewNumberValue(big.NewFloat(-0.12340984302980000)), expectation: "-0.123409843", }, "known-negative-less-than-one": { - input: NumberValue(big.NewFloat(-92387938173219.327663)), + input: NewNumberValue(big.NewFloat(-92387938173219.327663)), expectation: "-9.238793817e+13", }, "known-min-float64": { - input: NumberValue(big.NewFloat(math.SmallestNonzeroFloat64)), + input: NewNumberValue(big.NewFloat(math.SmallestNonzeroFloat64)), expectation: "4.940656458e-324", }, "known-max-float64": { - input: NumberValue(big.NewFloat(math.MaxFloat64)), + input: NewNumberValue(big.NewFloat(math.MaxFloat64)), expectation: "1.797693135e+308", }, "unknown": { - input: NumberUnknown(), + input: NewNumberUnknown(), expectation: "", }, "null": { - input: NumberNull(), + input: NewNumberNull(), expectation: "", }, } @@ -374,27 +366,27 @@ func TestNumberString(t *testing.T) { } } -func TestNumberValueBigFloat(t *testing.T) { +func TestNumberValueValueBigFloat(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Number + input NumberValue expected *big.Float }{ "known": { - input: NumberValue(big.NewFloat(2.4)), + input: NewNumberValue(big.NewFloat(2.4)), expected: big.NewFloat(2.4), }, "known-nil": { - input: NumberValue(nil), + input: NewNumberValue(nil), expected: nil, }, "null": { - input: NumberNull(), + input: NewNumberNull(), expected: nil, }, "unknown": { - input: NumberUnknown(), + input: NewNumberUnknown(), expected: nil, }, } diff --git a/types/basetypes/number_type.go b/types/basetypes/number_type.go new file mode 100644 index 000000000..75d70664f --- /dev/null +++ b/types/basetypes/number_type.go @@ -0,0 +1,84 @@ +package basetypes + +import ( + "context" + "fmt" + "math/big" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// NumberTypable extends attr.Type for number types. +// Implement this interface to create a custom NumberType type. +type NumberTypable interface { + attr.Type + + // ValueFromNumber should convert the Number to a NumberValuable type. + ValueFromNumber(context.Context, NumberValue) (NumberValuable, diag.Diagnostics) +} + +var _ NumberTypable = NumberType{} + +// NumberType is the base framework type for a floating point number. +// NumberValue is the associated value type. +type NumberType struct{} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// type. +func (t NumberType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// Equal returns true if the given type is equivalent. +func (t NumberType) Equal(o attr.Type) bool { + _, ok := o.(NumberType) + + return ok +} + +// String returns a human readable string of the type name. +func (t NumberType) String() string { + return "basetypes.NumberType" +} + +// TerraformType returns the tftypes.Type that should be used to represent this +// framework type. +func (t NumberType) TerraformType(_ context.Context) tftypes.Type { + return tftypes.Number +} + +// ValueFromNumber returns a NumberValuable type given a NumberValue. +func (t NumberType) ValueFromNumber(_ context.Context, v NumberValue) (NumberValuable, diag.Diagnostics) { + return v, nil +} + +// ValueFromTerraform returns a Value given a tftypes.Value. This is meant to +// convert the tftypes.Value into a more convenient Go type for the provider to +// consume the data with. +func (t NumberType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if !in.IsKnown() { + return NewNumberUnknown(), nil + } + + if in.IsNull() { + return NewNumberNull(), nil + } + + n := big.NewFloat(0) + + err := in.As(&n) + + if err != nil { + return nil, err + } + + return NewNumberValue(n), nil +} + +// ValueType returns the Value type. +func (t NumberType) ValueType(_ context.Context) attr.Value { + // This Value does not need to be valid. + return NumberValue{} +} diff --git a/types/object.go b/types/basetypes/object.go similarity index 84% rename from types/object.go rename to types/basetypes/object.go index 71cd7155b..74ee62ed2 100644 --- a/types/object.go +++ b/types/basetypes/object.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -16,7 +16,7 @@ import ( var ( _ ObjectTypable = ObjectType{} - _ ObjectValuable = &Object{} + _ ObjectValuable = &ObjectValue{} ) // ObjectTypable extends attr.Type for object types. @@ -25,7 +25,7 @@ type ObjectTypable interface { attr.Type // ValueFromObject should convert the Object to an ObjectValuable type. - ValueFromObject(context.Context, Object) (ObjectValuable, diag.Diagnostics) + ValueFromObject(context.Context, ObjectValue) (ObjectValuable, diag.Diagnostics) } // ObjectValuable extends attr.Value for object value types. @@ -34,7 +34,7 @@ type ObjectValuable interface { attr.Value // ToObjectValue should convert the value type to an Object. - ToObjectValue(ctx context.Context) (Object, diag.Diagnostics) + ToObjectValue(ctx context.Context) (ObjectValue, diag.Diagnostics) } // ObjectType is an AttributeType representing an object. @@ -75,16 +75,16 @@ func (o ObjectType) TerraformType(ctx context.Context) tftypes.Type { // type for the provider to consume the data with. func (o ObjectType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { if in.Type() == nil { - return ObjectNull(o.AttrTypes), nil + return NewObjectNull(o.AttrTypes), nil } if !in.Type().Equal(o.TerraformType(ctx)) { return nil, fmt.Errorf("expected %s, got %s", o.TerraformType(ctx), in.Type()) } if !in.IsKnown() { - return ObjectUnknown(o.AttrTypes), nil + return NewObjectUnknown(o.AttrTypes), nil } if in.IsNull() { - return ObjectNull(o.AttrTypes), nil + return NewObjectNull(o.AttrTypes), nil } attributes := map[string]attr.Value{} @@ -103,7 +103,7 @@ func (o ObjectType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (a } // ValueFromTerraform above on each attribute should make this safe. // Otherwise, this will need to do some Diagnostics to error conversion. - return ObjectValueMust(o.AttrTypes, attributes), nil + return NewObjectValueMust(o.AttrTypes, attributes), nil } // Equal returns true if `candidate` is also an ObjectType and has the same @@ -160,37 +160,37 @@ func (o ObjectType) String() string { // ValueType returns the Value type. func (o ObjectType) ValueType(_ context.Context) attr.Value { - return Object{ + return ObjectValue{ attributeTypes: o.AttrTypes, } } // ValueFromObject returns an ObjectValuable type given an Object. -func (o ObjectType) ValueFromObject(_ context.Context, obj Object) (ObjectValuable, diag.Diagnostics) { +func (o ObjectType) ValueFromObject(_ context.Context, obj ObjectValue) (ObjectValuable, diag.Diagnostics) { return obj, nil } -// ObjectNull creates a Object with a null value. Determine whether the value is +// NewObjectNull creates a Object with a null value. Determine whether the value is // null via the Object type IsNull method. -func ObjectNull(attributeTypes map[string]attr.Type) Object { - return Object{ +func NewObjectNull(attributeTypes map[string]attr.Type) ObjectValue { + return ObjectValue{ attributeTypes: attributeTypes, state: attr.ValueStateNull, } } -// ObjectUnknown creates a Object with an unknown value. Determine whether the +// NewObjectUnknown creates a Object with an unknown value. Determine whether the // value is unknown via the Object type IsUnknown method. -func ObjectUnknown(attributeTypes map[string]attr.Type) Object { - return Object{ +func NewObjectUnknown(attributeTypes map[string]attr.Type) ObjectValue { + return ObjectValue{ attributeTypes: attributeTypes, state: attr.ValueStateUnknown, } } -// ObjectValue creates a Object with a known value. Access the value via the Object +// NewObjectValue creates a Object with a known value. Access the value via the Object // type ElementsAs method. -func ObjectValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (Object, diag.Diagnostics) { +func NewObjectValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (ObjectValue, diag.Diagnostics) { var diags diag.Diagnostics // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 @@ -238,21 +238,21 @@ func ObjectValue(attributeTypes map[string]attr.Type, attributes map[string]attr } if diags.HasError() { - return ObjectUnknown(attributeTypes), diags + return NewObjectUnknown(attributeTypes), diags } - return Object{ + return ObjectValue{ attributeTypes: attributeTypes, attributes: attributes, state: attr.ValueStateKnown, }, nil } -// ObjectValueFrom creates a Object with a known value, using reflection rules. +// NewObjectValueFrom creates a Object with a known value, using reflection rules. // The attributes must be a map of string attribute names to attribute values // which can convert into the given attribute type or a struct with tfsdk field // tags. Access the value via the Object type Elements or ElementsAs methods. -func ObjectValueFrom(ctx context.Context, attributeTypes map[string]attr.Type, attributes any) (Object, diag.Diagnostics) { +func NewObjectValueFrom(ctx context.Context, attributeTypes map[string]attr.Type, attributes any) (ObjectValue, diag.Diagnostics) { attrValue, diags := reflect.FromValue( ctx, ObjectType{AttrTypes: attributeTypes}, @@ -261,10 +261,10 @@ func ObjectValueFrom(ctx context.Context, attributeTypes map[string]attr.Type, a ) if diags.HasError() { - return ObjectUnknown(attributeTypes), diags + return NewObjectUnknown(attributeTypes), diags } - m, ok := attrValue.(Object) + m, ok := attrValue.(ObjectValue) // This should not happen, but ensure there is an error if it does. if !ok { @@ -278,15 +278,15 @@ func ObjectValueFrom(ctx context.Context, attributeTypes map[string]attr.Type, a return m, diags } -// ObjectValueMust creates a Object with a known value, converting any diagnostics +// NewObjectValueMust creates a Object with a known value, converting any diagnostics // into a panic at runtime. Access the value via the Object // type Elements or ElementsAs methods. // // This creation function is only recommended to create Object values which will // not potentially effect practitioners, such as testing, or exhaustively // tested provider logic. -func ObjectValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) Object { - object, diags := ObjectValue(attributeTypes, attributes) +func NewObjectValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) ObjectValue { + object, diags := NewObjectValue(attributeTypes, attributes) if diags.HasError() { // This could potentially be added to the diag package. @@ -306,8 +306,8 @@ func ObjectValueMust(attributeTypes map[string]attr.Type, attributes map[string] return object } -// Object represents an object -type Object struct { +// ObjectValue represents an object +type ObjectValue struct { // attributes is the mapping of known attribute values in the Object. attributes map[string]attr.Value @@ -335,9 +335,9 @@ type ObjectAsOptions struct { UnhandledUnknownAsEmpty bool } -// As populates `target` with the data in the Object, throwing an error if the +// As populates `target` with the data in the ObjectValue, throwing an error if the // data cannot be stored in `target`. -func (o Object) As(ctx context.Context, target interface{}, opts ObjectAsOptions) diag.Diagnostics { +func (o ObjectValue) As(ctx context.Context, target interface{}, opts ObjectAsOptions) diag.Diagnostics { // we need a tftypes.Value for this Object to be able to use it with // our reflection code obj := ObjectType{AttrTypes: o.attributeTypes} @@ -358,23 +358,23 @@ func (o Object) As(ctx context.Context, target interface{}, opts ObjectAsOptions // Attributes returns the mapping of known attribute values for the Object. // Returns nil if the Object is null or unknown. -func (o Object) Attributes() map[string]attr.Value { +func (o ObjectValue) Attributes() map[string]attr.Value { return o.attributes } // AttributeTypes returns the mapping of attribute types for the Object. -func (o Object) AttributeTypes(_ context.Context) map[string]attr.Type { +func (o ObjectValue) AttributeTypes(_ context.Context) map[string]attr.Type { return o.attributeTypes } // Type returns an ObjectType with the same attribute types as `o`. -func (o Object) Type(ctx context.Context) attr.Type { +func (o ObjectValue) Type(ctx context.Context) attr.Type { return ObjectType{AttrTypes: o.AttributeTypes(ctx)} } // ToTerraformValue returns the data contained in the attr.Value as // a tftypes.Value. -func (o Object) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { +func (o ObjectValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { attrTypes := map[string]tftypes.Type{} for attr, typ := range o.AttributeTypes(ctx) { attrTypes[attr] = typ.TerraformType(ctx) @@ -411,8 +411,8 @@ func (o Object) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { // Equal returns true if the Object is considered semantically equal // (same type and same value) to the attr.Value passed as an argument. -func (o Object) Equal(c attr.Value) bool { - other, ok := c.(Object) +func (o ObjectValue) Equal(c attr.Value) bool { + other, ok := c.(ObjectValue) if !ok { return false @@ -462,19 +462,19 @@ func (o Object) Equal(c attr.Value) bool { } // IsNull returns true if the Object represents a null value. -func (o Object) IsNull() bool { +func (o ObjectValue) IsNull() bool { return o.state == attr.ValueStateNull } // IsUnknown returns true if the Object represents a currently unknown value. -func (o Object) IsUnknown() bool { +func (o ObjectValue) IsUnknown() bool { return o.state == attr.ValueStateUnknown } // String returns a human-readable representation of the Object value. // The string returned here is not protected by any compatibility guarantees, // and is intended for logging and error reporting. -func (o Object) String() string { +func (o ObjectValue) String() string { if o.IsUnknown() { return attr.UnknownValueString } @@ -505,6 +505,6 @@ func (o Object) String() string { } // ToObjectValue returns the Object. -func (o Object) ToObjectValue(context.Context) (Object, diag.Diagnostics) { +func (o ObjectValue) ToObjectValue(context.Context) (ObjectValue, diag.Diagnostics) { return o, nil } diff --git a/types/object_test.go b/types/basetypes/object_test.go similarity index 58% rename from types/object_test.go rename to types/basetypes/object_test.go index 7cbc69996..9b8e71e4e 100644 --- a/types/object_test.go +++ b/types/basetypes/object_test.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -16,9 +16,9 @@ func TestObjectTypeTerraformType_simple(t *testing.T) { t.Parallel() result := ObjectType{ AttrTypes: map[string]attr.Type{ - "foo": StringType, - "bar": NumberType, - "baz": BoolType, + "foo": StringType{}, + "bar": NumberType{}, + "baz": BoolType{}, }, }.TerraformType(context.Background()) if diff := cmp.Diff(result, tftypes.Object{ @@ -55,9 +55,9 @@ func TestObjectTypeValueFromTerraform(t *testing.T) { "basic-object": { receiver: ObjectType{ AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": BoolType, - "c": NumberType, + "a": StringType{}, + "b": BoolType{}, + "c": NumberType{}, }, }, input: tftypes.NewValue(tftypes.Object{ @@ -71,23 +71,23 @@ func TestObjectTypeValueFromTerraform(t *testing.T) { "b": tftypes.NewValue(tftypes.Bool, true), "c": tftypes.NewValue(tftypes.Number, 123), }), - expected: ObjectValueMust( + expected: NewObjectValueMust( map[string]attr.Type{ - "a": StringType, - "b": BoolType, - "c": NumberType, + "a": StringType{}, + "b": BoolType{}, + "c": NumberType{}, }, map[string]attr.Value{ - "a": StringValue("red"), - "b": BoolValue(true), - "c": NumberValue(big.NewFloat(123)), + "a": NewStringValue("red"), + "b": NewBoolValue(true), + "c": NewNumberValue(big.NewFloat(123)), }, ), }, "extra-attribute": { receiver: ObjectType{ AttrTypes: map[string]attr.Type{ - "a": StringType, + "a": StringType{}, }, }, input: tftypes.NewValue(tftypes.Object{ @@ -104,8 +104,8 @@ func TestObjectTypeValueFromTerraform(t *testing.T) { "missing-attribute": { receiver: ObjectType{ AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": BoolType, + "a": StringType{}, + "b": BoolType{}, }, }, input: tftypes.NewValue(tftypes.Object{ @@ -120,7 +120,7 @@ func TestObjectTypeValueFromTerraform(t *testing.T) { "wrong-type": { receiver: ObjectType{ AttrTypes: map[string]attr.Type{ - "a": StringType, + "a": StringType{}, }, }, input: tftypes.NewValue(tftypes.String, "hello"), @@ -129,20 +129,20 @@ func TestObjectTypeValueFromTerraform(t *testing.T) { "nil-type": { receiver: ObjectType{ AttrTypes: map[string]attr.Type{ - "a": StringType, + "a": StringType{}, }, }, input: tftypes.NewValue(nil, nil), - expected: ObjectNull( + expected: NewObjectNull( map[string]attr.Type{ - "a": StringType, + "a": StringType{}, }, ), }, "unknown": { receiver: ObjectType{ AttrTypes: map[string]attr.Type{ - "a": StringType, + "a": StringType{}, }, }, input: tftypes.NewValue(tftypes.Object{ @@ -150,16 +150,16 @@ func TestObjectTypeValueFromTerraform(t *testing.T) { "a": tftypes.String, }, }, tftypes.UnknownValue), - expected: ObjectUnknown( + expected: NewObjectUnknown( map[string]attr.Type{ - "a": StringType, + "a": StringType{}, }, ), }, "null": { receiver: ObjectType{ AttrTypes: map[string]attr.Type{ - "a": StringType, + "a": StringType{}, }, }, input: tftypes.NewValue(tftypes.Object{ @@ -167,9 +167,9 @@ func TestObjectTypeValueFromTerraform(t *testing.T) { "a": tftypes.String, }, }, nil), - expected: ObjectNull( + expected: NewObjectNull( map[string]attr.Type{ - "a": StringType, + "a": StringType{}, }, ), }, @@ -219,112 +219,112 @@ func TestObjectTypeEqual(t *testing.T) { tests := map[string]testCase{ "equal": { receiver: ObjectType{AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": NumberType, - "c": BoolType, + "a": StringType{}, + "b": NumberType{}, + "c": BoolType{}, "d": ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }}, input: ObjectType{AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": NumberType, - "c": BoolType, + "a": StringType{}, + "b": NumberType{}, + "c": BoolType{}, "d": ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }}, expected: true, }, "missing-attr": { receiver: ObjectType{AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": NumberType, - "c": BoolType, + "a": StringType{}, + "b": NumberType{}, + "c": BoolType{}, "d": ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }}, input: ObjectType{AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": NumberType, + "a": StringType{}, + "b": NumberType{}, "d": ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }}, expected: false, }, "extra-attr": { receiver: ObjectType{AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": NumberType, + "a": StringType{}, + "b": NumberType{}, "d": ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }}, input: ObjectType{AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": NumberType, - "c": BoolType, + "a": StringType{}, + "b": NumberType{}, + "c": BoolType{}, "d": ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }}, expected: false, }, "diff-attrs": { receiver: ObjectType{AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": NumberType, - "e": BoolType, + "a": StringType{}, + "b": NumberType{}, + "e": BoolType{}, "d": ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }}, input: ObjectType{AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": NumberType, - "c": BoolType, + "a": StringType{}, + "b": NumberType{}, + "c": BoolType{}, "d": ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }}, expected: false, }, "diff": { receiver: ObjectType{AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": BoolType, - "c": BoolType, + "a": StringType{}, + "b": BoolType{}, + "c": BoolType{}, "d": ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }}, input: ObjectType{AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": NumberType, - "c": BoolType, + "a": StringType{}, + "b": NumberType{}, + "c": BoolType{}, "d": ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }}, expected: false, }, "nested-diff": { receiver: ObjectType{AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": NumberType, - "c": BoolType, + "a": StringType{}, + "b": NumberType{}, + "c": BoolType{}, "d": ListType{ - ElemType: StringType, + ElemType: StringType{}, }, }}, input: ObjectType{AttrTypes: map[string]attr.Type{ - "a": StringType, - "b": NumberType, - "c": BoolType, + "a": StringType{}, + "b": NumberType{}, + "c": BoolType{}, "d": ListType{ - ElemType: BoolType, + ElemType: BoolType{}, }, }}, expected: false, @@ -332,16 +332,16 @@ func TestObjectTypeEqual(t *testing.T) { "wrongType": { receiver: ObjectType{ AttrTypes: map[string]attr.Type{ - "a": StringType, + "a": StringType{}, }, }, - input: NumberType, + input: NumberType{}, expected: false, }, "nil": { receiver: ObjectType{ AttrTypes: map[string]attr.Type{ - "a": StringType, + "a": StringType{}, }, }, input: nil, @@ -366,56 +366,56 @@ func TestObjectTypeEqual(t *testing.T) { } } -func TestObjectValue(t *testing.T) { +func TestNewObjectValue(t *testing.T) { t.Parallel() testCases := map[string]struct { attributeTypes map[string]attr.Type attributes map[string]attr.Value - expected Object + expected ObjectValue expectedDiags diag.Diagnostics }{ "valid-no-attributes": { attributeTypes: map[string]attr.Type{}, attributes: map[string]attr.Value{}, - expected: ObjectValueMust(map[string]attr.Type{}, map[string]attr.Value{}), + expected: NewObjectValueMust(map[string]attr.Type{}, map[string]attr.Value{}), }, "valid-attributes": { attributeTypes: map[string]attr.Type{ - "null": StringType, - "unknown": StringType, - "known": StringType, + "null": StringType{}, + "unknown": StringType{}, + "known": StringType{}, }, attributes: map[string]attr.Value{ - "null": StringNull(), - "unknown": StringUnknown(), - "known": StringValue("test"), + "null": NewStringNull(), + "unknown": NewStringUnknown(), + "known": NewStringValue("test"), }, - expected: ObjectValueMust( + expected: NewObjectValueMust( map[string]attr.Type{ - "null": StringType, - "unknown": StringType, - "known": StringType, + "null": StringType{}, + "unknown": StringType{}, + "known": StringType{}, }, map[string]attr.Value{ - "null": StringNull(), - "unknown": StringUnknown(), - "known": StringValue("test"), + "null": NewStringNull(), + "unknown": NewStringUnknown(), + "known": NewStringValue("test"), }, ), }, "invalid-attribute-value": { attributeTypes: map[string]attr.Type{ - "string": StringType, - "bool": BoolType, + "string": StringType{}, + "bool": BoolType{}, }, attributes: map[string]attr.Value{ - "string": StringValue("test"), - "bool": StringValue("test"), + "string": NewStringValue("test"), + "bool": NewStringValue("test"), }, - expected: ObjectUnknown(map[string]attr.Type{ - "string": StringType, - "bool": BoolType, + expected: NewObjectUnknown(map[string]attr.Type{ + "string": StringType{}, + "bool": BoolType{}, }), expectedDiags: diag.Diagnostics{ diag.NewErrorDiagnostic( @@ -423,21 +423,21 @@ func TestObjectValue(t *testing.T) { "While creating a Object value, an invalid attribute value was detected. "+ "A Object must use a matching attribute type for the value. "+ "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ - "Object Attribute Name (bool) Expected Type: types.BoolType\n"+ - "Object Attribute Name (bool) Given Type: types.StringType", + "Object Attribute Name (bool) Expected Type: basetypes.BoolType\n"+ + "Object Attribute Name (bool) Given Type: basetypes.StringType", ), }, }, "invalid-extra-attribute": { attributeTypes: map[string]attr.Type{ - "string": StringType, + "string": StringType{}, }, attributes: map[string]attr.Value{ - "string": StringValue("test"), - "bool": BoolValue(true), + "string": NewStringValue("test"), + "bool": NewBoolValue(true), }, - expected: ObjectUnknown(map[string]attr.Type{ - "string": StringType, + expected: NewObjectUnknown(map[string]attr.Type{ + "string": StringType{}, }), expectedDiags: diag.Diagnostics{ diag.NewErrorDiagnostic( @@ -451,15 +451,15 @@ func TestObjectValue(t *testing.T) { }, "invalid-missing-attribute": { attributeTypes: map[string]attr.Type{ - "string": StringType, - "bool": BoolType, + "string": StringType{}, + "bool": BoolType{}, }, attributes: map[string]attr.Value{ - "string": StringValue("test"), + "string": NewStringValue("test"), }, - expected: ObjectUnknown(map[string]attr.Type{ - "string": StringType, - "bool": BoolType, + expected: NewObjectUnknown(map[string]attr.Type{ + "string": StringType{}, + "bool": BoolType{}, }), expectedDiags: diag.Diagnostics{ diag.NewErrorDiagnostic( @@ -467,7 +467,7 @@ func TestObjectValue(t *testing.T) { "While creating a Object value, a missing attribute value was detected. "+ "A Object must contain values for all attributes, even if null or unknown. "+ "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ - "Object Attribute Name (bool) Expected Type: types.BoolType", + "Object Attribute Name (bool) Expected Type: basetypes.BoolType", ), }, }, @@ -479,7 +479,7 @@ func TestObjectValue(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - got, diags := ObjectValue(testCase.attributeTypes, testCase.attributes) + got, diags := NewObjectValue(testCase.attributeTypes, testCase.attributes) if diff := cmp.Diff(got, testCase.expected); diff != "" { t.Errorf("unexpected difference: %s", diff) @@ -492,71 +492,71 @@ func TestObjectValue(t *testing.T) { } } -func TestObjectValueFrom(t *testing.T) { +func TestNewObjectValueFrom(t *testing.T) { t.Parallel() testCases := map[string]struct { attributeTypes map[string]attr.Type attributes any - expected Object + expected ObjectValue expectedDiags diag.Diagnostics }{ "valid-*struct": { attributeTypes: map[string]attr.Type{ - "bool": BoolType, - "string": StringType, + "bool": BoolType{}, + "string": StringType{}, }, attributes: pointer(struct { - Bool Bool `tfsdk:"bool"` - String String `tfsdk:"string"` + Bool BoolValue `tfsdk:"bool"` + String StringValue `tfsdk:"string"` }{ - Bool: BoolValue(true), - String: StringValue("test"), + Bool: NewBoolValue(true), + String: NewStringValue("test"), }), - expected: ObjectValueMust( + expected: NewObjectValueMust( map[string]attr.Type{ - "bool": BoolType, - "string": StringType, + "bool": BoolType{}, + "string": StringType{}, }, map[string]attr.Value{ - "bool": BoolValue(true), - "string": StringValue("test"), + "bool": NewBoolValue(true), + "string": NewStringValue("test"), }, ), }, "valid-struct": { attributeTypes: map[string]attr.Type{ - "bool": BoolType, - "string": StringType, + "bool": BoolType{}, + "string": StringType{}, }, attributes: struct { - Bool Bool `tfsdk:"bool"` - String String `tfsdk:"string"` + Bool BoolValue `tfsdk:"bool"` + String StringValue `tfsdk:"string"` }{ - Bool: BoolValue(true), - String: StringValue("test"), + Bool: NewBoolValue(true), + String: NewStringValue("test"), }, - expected: ObjectValueMust( + expected: NewObjectValueMust( map[string]attr.Type{ - "bool": BoolType, - "string": StringType, + "bool": BoolType{}, + "string": StringType{}, }, map[string]attr.Value{ - "bool": BoolValue(true), - "string": StringValue("test"), + "bool": NewBoolValue(true), + "string": NewStringValue("test"), }, ), }, "invalid-nil": { attributeTypes: map[string]attr.Type{ - "string": StringType, - "bool": BoolType, + "string": StringType{}, + "bool": BoolType{}, }, attributes: nil, - expected: ObjectUnknown( + expected: NewObjectUnknown( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, + "string": StringType{}, + "bool": BoolType{}, }, ), expectedDiags: diag.Diagnostics{ @@ -571,17 +571,17 @@ func TestObjectValueFrom(t *testing.T) { // This likely should be valid, however it is not currently. "invalid-map[string]attr.Value": { attributeTypes: map[string]attr.Type{ - "bool": BoolType, - "string": StringType, + "bool": BoolType{}, + "string": StringType{}, }, attributes: map[string]attr.Value{ - "bool": BoolNull(), - "string": StringNull(), + "bool": NewBoolNull(), + "string": NewStringNull(), }, - expected: ObjectUnknown( + expected: NewObjectUnknown( map[string]attr.Type{ - "bool": BoolType, - "string": StringType, + "bool": BoolType{}, + "string": StringType{}, }, ), expectedDiags: diag.Diagnostics{ @@ -589,19 +589,19 @@ func TestObjectValueFrom(t *testing.T) { path.Empty(), "Value Conversion Error", "An unexpected error was encountered trying to convert from value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ - "cannot use type map[string]attr.Value as schema type types.ObjectType; types.ObjectType must be an attr.TypeWithElementType to hold map[string]attr.Value", + "cannot use type map[string]attr.Value as schema type basetypes.ObjectType; basetypes.ObjectType must be an attr.TypeWithElementType to hold map[string]attr.Value", ), }, }, "invalid-not-struct": { attributeTypes: map[string]attr.Type{ - "string": StringType, - "bool": BoolType, + "string": StringType{}, + "bool": BoolType{}, }, attributes: "oops", - expected: ObjectUnknown(map[string]attr.Type{ - "string": StringType, - "bool": BoolType, + expected: NewObjectUnknown(map[string]attr.Type{ + "string": StringType{}, + "bool": BoolType{}, }), expectedDiags: diag.Diagnostics{ diag.NewAttributeErrorDiagnostic( @@ -614,20 +614,20 @@ func TestObjectValueFrom(t *testing.T) { }, "invalid-type": { attributeTypes: map[string]attr.Type{ - "string": StringType, - "bool": BoolType, + "string": StringType{}, + "bool": BoolType{}, }, attributes: map[string]bool{"key1": true}, - expected: ObjectUnknown(map[string]attr.Type{ - "string": StringType, - "bool": BoolType, + expected: NewObjectUnknown(map[string]attr.Type{ + "string": StringType{}, + "bool": BoolType{}, }), expectedDiags: diag.Diagnostics{ diag.NewAttributeErrorDiagnostic( path.Empty(), "Value Conversion Error", "An unexpected error was encountered trying to convert from value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ - "cannot use type map[string]bool as schema type types.ObjectType; types.ObjectType must be an attr.TypeWithElementType to hold map[string]bool", + "cannot use type map[string]bool as schema type basetypes.ObjectType; basetypes.ObjectType must be an attr.TypeWithElementType to hold map[string]bool", ), }, }, @@ -639,7 +639,7 @@ func TestObjectValueFrom(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - got, diags := ObjectValueFrom(context.Background(), testCase.attributeTypes, testCase.attributes) + got, diags := NewObjectValueFrom(context.Background(), testCase.attributeTypes, testCase.attributes) if diff := cmp.Diff(got, testCase.expected); diff != "" { t.Errorf("unexpected difference: %s", diff) @@ -659,164 +659,164 @@ func TestObjectAs_struct(t *testing.T) { t.Parallel() type myEmbeddedStruct struct { - Red string `tfsdk:"red"` - Blue List `tfsdk:"blue"` - Green Number `tfsdk:"green"` - Yellow int `tfsdk:"yellow"` + Red string `tfsdk:"red"` + Blue ListValue `tfsdk:"blue"` + Green NumberValue `tfsdk:"green"` + Yellow int `tfsdk:"yellow"` } type myStruct struct { A string `tfsdk:"a"` - B Bool `tfsdk:"b"` - C List `tfsdk:"c"` + B BoolValue `tfsdk:"b"` + C ListValue `tfsdk:"c"` D []string `tfsdk:"d"` - E []Bool `tfsdk:"e"` - F []List `tfsdk:"f"` - G Object `tfsdk:"g"` + E []BoolValue `tfsdk:"e"` + F []ListValue `tfsdk:"f"` + G ObjectValue `tfsdk:"g"` H myEmbeddedStruct `tfsdk:"h"` - I Object `tfsdk:"i"` + I ObjectValue `tfsdk:"i"` } - object := ObjectValueMust( + object := NewObjectValueMust( map[string]attr.Type{ - "a": StringType, - "b": BoolType, - "c": ListType{ElemType: StringType}, - "d": ListType{ElemType: StringType}, - "e": ListType{ElemType: BoolType}, - "f": ListType{ElemType: ListType{ElemType: StringType}}, + "a": StringType{}, + "b": BoolType{}, + "c": ListType{ElemType: StringType{}}, + "d": ListType{ElemType: StringType{}}, + "e": ListType{ElemType: BoolType{}}, + "f": ListType{ElemType: ListType{ElemType: StringType{}}}, "g": ObjectType{ AttrTypes: map[string]attr.Type{ - "dogs": NumberType, - "cats": NumberType, - "names": ListType{ElemType: StringType}, + "dogs": NumberType{}, + "cats": NumberType{}, + "names": ListType{ElemType: StringType{}}, }, }, "h": ObjectType{ AttrTypes: map[string]attr.Type{ - "red": StringType, - "blue": ListType{ElemType: NumberType}, - "green": NumberType, - "yellow": NumberType, + "red": StringType{}, + "blue": ListType{ElemType: NumberType{}}, + "green": NumberType{}, + "yellow": NumberType{}, }, }, "i": ObjectType{ AttrTypes: map[string]attr.Type{ - "name": StringType, - "age": NumberType, - "opted_in": BoolType, + "name": StringType{}, + "age": NumberType{}, + "opted_in": BoolType{}, }, }, }, map[string]attr.Value{ - "a": StringValue("hello"), - "b": BoolValue(true), - "c": ListValueMust( - StringType, + "a": NewStringValue("hello"), + "b": NewBoolValue(true), + "c": NewListValueMust( + StringType{}, []attr.Value{ - StringValue("into"), - StringValue("the"), - StringUnknown(), - StringNull(), + NewStringValue("into"), + NewStringValue("the"), + NewStringUnknown(), + NewStringNull(), }, ), - "d": ListValueMust( - StringType, + "d": NewListValueMust( + StringType{}, []attr.Value{ - StringValue("it's"), - StringValue("getting"), - StringValue("hard"), - StringValue("to"), - StringValue("come"), - StringValue("up"), - StringValue("with"), - StringValue("test"), - StringValue("values"), + NewStringValue("it's"), + NewStringValue("getting"), + NewStringValue("hard"), + NewStringValue("to"), + NewStringValue("come"), + NewStringValue("up"), + NewStringValue("with"), + NewStringValue("test"), + NewStringValue("values"), }, ), - "e": ListValueMust( - BoolType, + "e": NewListValueMust( + BoolType{}, []attr.Value{ - BoolValue(true), - BoolValue(false), - BoolValue(false), - BoolValue(true), + NewBoolValue(true), + NewBoolValue(false), + NewBoolValue(false), + NewBoolValue(true), }, ), - "f": ListValueMust( + "f": NewListValueMust( ListType{ - ElemType: StringType, + ElemType: StringType{}, }, []attr.Value{ - ListValueMust( - StringType, + NewListValueMust( + StringType{}, []attr.Value{ - StringValue("head"), - StringValue("empty"), + NewStringValue("head"), + NewStringValue("empty"), }, ), - ListValueMust( - StringType, + NewListValueMust( + StringType{}, []attr.Value{ - StringValue("no"), - StringValue("thoughts"), + NewStringValue("no"), + NewStringValue("thoughts"), }, ), }, ), - "g": ObjectValueMust( + "g": NewObjectValueMust( map[string]attr.Type{ - "dogs": NumberType, - "cats": NumberType, - "names": ListType{ElemType: StringType}, + "dogs": NumberType{}, + "cats": NumberType{}, + "names": ListType{ElemType: StringType{}}, }, map[string]attr.Value{ - "dogs": NumberValue(big.NewFloat(3)), - "cats": NumberValue(big.NewFloat(5)), - "names": ListValueMust( - StringType, + "dogs": NewNumberValue(big.NewFloat(3)), + "cats": NewNumberValue(big.NewFloat(5)), + "names": NewListValueMust( + StringType{}, []attr.Value{ - StringValue("Roxy"), - StringValue("Jpeg"), - StringValue("Kupo"), - StringValue("Clawde"), - StringValue("Yeti"), - StringValue("Abby"), - StringValue("Ellie"), - StringValue("Lexi"), + NewStringValue("Roxy"), + NewStringValue("Jpeg"), + NewStringValue("Kupo"), + NewStringValue("Clawde"), + NewStringValue("Yeti"), + NewStringValue("Abby"), + NewStringValue("Ellie"), + NewStringValue("Lexi"), }, ), }, ), - "h": ObjectValueMust( + "h": NewObjectValueMust( map[string]attr.Type{ - "red": StringType, - "blue": ListType{ElemType: NumberType}, - "green": NumberType, - "yellow": NumberType, + "red": StringType{}, + "blue": ListType{ElemType: NumberType{}}, + "green": NumberType{}, + "yellow": NumberType{}, }, map[string]attr.Value{ - "red": StringValue("judge me not too harshly, future maintainers, this much random data is hard to come up with without getting weird."), - "blue": ListValueMust( - NumberType, + "red": NewStringValue("judge me not too harshly, future maintainers, this much random data is hard to come up with without getting weird."), + "blue": NewListValueMust( + NumberType{}, []attr.Value{ - NumberValue(big.NewFloat(1)), - NumberValue(big.NewFloat(2)), - NumberValue(big.NewFloat(3)), + NewNumberValue(big.NewFloat(1)), + NewNumberValue(big.NewFloat(2)), + NewNumberValue(big.NewFloat(3)), }, ), - "green": NumberValue(big.NewFloat(123.456)), - "yellow": NumberValue(big.NewFloat(123)), + "green": NewNumberValue(big.NewFloat(123.456)), + "yellow": NewNumberValue(big.NewFloat(123)), }, ), - "i": ObjectValueMust( + "i": NewObjectValueMust( map[string]attr.Type{ - "name": StringType, - "age": NumberType, - "opted_in": BoolType, + "name": StringType{}, + "age": NumberType{}, + "opted_in": BoolType{}, }, map[string]attr.Value{ - "name": StringValue("J Doe"), - "age": NumberValue(big.NewFloat(28)), - "opted_in": BoolValue(true), + "name": NewStringValue("J Doe"), + "age": NewNumberValue(big.NewFloat(28)), + "opted_in": NewBoolValue(true), }, ), }, @@ -828,86 +828,86 @@ func TestObjectAs_struct(t *testing.T) { } expected := myStruct{ A: "hello", - B: BoolValue(true), - C: ListValueMust( - StringType, + B: NewBoolValue(true), + C: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("into"), - StringValue("the"), - StringUnknown(), - StringNull(), + NewStringValue("into"), + NewStringValue("the"), + NewStringUnknown(), + NewStringNull(), }, ), D: []string{"it's", "getting", "hard", "to", "come", "up", "with", "test", "values"}, - E: []Bool{ - BoolValue(true), - BoolValue(false), - BoolValue(false), - BoolValue(true), - }, - F: []List{ - ListValueMust( - StringType, + E: []BoolValue{ + NewBoolValue(true), + NewBoolValue(false), + NewBoolValue(false), + NewBoolValue(true), + }, + F: []ListValue{ + NewListValueMust( + StringType{}, []attr.Value{ - StringValue("head"), - StringValue("empty"), + NewStringValue("head"), + NewStringValue("empty"), }, ), - ListValueMust( - StringType, + NewListValueMust( + StringType{}, []attr.Value{ - StringValue("no"), - StringValue("thoughts"), + NewStringValue("no"), + NewStringValue("thoughts"), }, ), }, - G: ObjectValueMust( + G: NewObjectValueMust( map[string]attr.Type{ - "dogs": NumberType, - "cats": NumberType, - "names": ListType{ElemType: StringType}, + "dogs": NumberType{}, + "cats": NumberType{}, + "names": ListType{ElemType: StringType{}}, }, map[string]attr.Value{ - "dogs": NumberValue(big.NewFloat(3)), - "cats": NumberValue(big.NewFloat(5)), - "names": ListValueMust( - StringType, + "dogs": NewNumberValue(big.NewFloat(3)), + "cats": NewNumberValue(big.NewFloat(5)), + "names": NewListValueMust( + StringType{}, []attr.Value{ - StringValue("Roxy"), - StringValue("Jpeg"), - StringValue("Kupo"), - StringValue("Clawde"), - StringValue("Yeti"), - StringValue("Abby"), - StringValue("Ellie"), - StringValue("Lexi"), + NewStringValue("Roxy"), + NewStringValue("Jpeg"), + NewStringValue("Kupo"), + NewStringValue("Clawde"), + NewStringValue("Yeti"), + NewStringValue("Abby"), + NewStringValue("Ellie"), + NewStringValue("Lexi"), }, ), }, ), H: myEmbeddedStruct{ Red: "judge me not too harshly, future maintainers, this much random data is hard to come up with without getting weird.", - Blue: ListValueMust( - NumberType, + Blue: NewListValueMust( + NumberType{}, []attr.Value{ - NumberValue(big.NewFloat(1)), - NumberValue(big.NewFloat(2)), - NumberValue(big.NewFloat(3)), + NewNumberValue(big.NewFloat(1)), + NewNumberValue(big.NewFloat(2)), + NewNumberValue(big.NewFloat(3)), }, ), - Green: NumberValue(big.NewFloat(123.456)), + Green: NewNumberValue(big.NewFloat(123.456)), Yellow: 123, }, - I: ObjectValueMust( + I: NewObjectValueMust( map[string]attr.Type{ - "name": StringType, - "age": NumberType, - "opted_in": BoolType, + "name": StringType{}, + "age": NumberType{}, + "opted_in": BoolType{}, }, map[string]attr.Value{ - "name": StringValue("J Doe"), - "age": NumberValue(big.NewFloat(28)), - "opted_in": BoolValue(true), + "name": NewStringValue("J Doe"), + "age": NewNumberValue(big.NewFloat(28)), + "opted_in": NewBoolValue(true), }, ), } @@ -916,26 +916,26 @@ func TestObjectAs_struct(t *testing.T) { } } -func TestObjectAttributes(t *testing.T) { +func TestObjectValueAttributes(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Object + input ObjectValue expected map[string]attr.Value }{ "known": { - input: ObjectValueMust( - map[string]attr.Type{"test_attr": StringType}, - map[string]attr.Value{"test_attr": StringValue("test-value")}, + input: NewObjectValueMust( + map[string]attr.Type{"test_attr": StringType{}}, + map[string]attr.Value{"test_attr": NewStringValue("test-value")}, ), - expected: map[string]attr.Value{"test_attr": StringValue("test-value")}, + expected: map[string]attr.Value{"test_attr": NewStringValue("test-value")}, }, "null": { - input: ObjectNull(map[string]attr.Type{"test_attr": StringType}), + input: NewObjectNull(map[string]attr.Type{"test_attr": StringType{}}), expected: nil, }, "unknown": { - input: ObjectUnknown(map[string]attr.Type{"test_attr": StringType}), + input: NewObjectUnknown(map[string]attr.Type{"test_attr": StringType{}}), expected: nil, }, } @@ -955,27 +955,27 @@ func TestObjectAttributes(t *testing.T) { } } -func TestObjectAttributeTypes(t *testing.T) { +func TestObjectValueAttributeTypes(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Object + input ObjectValue expected map[string]attr.Type }{ "known": { - input: ObjectValueMust( - map[string]attr.Type{"test_attr": StringType}, - map[string]attr.Value{"test_attr": StringValue("test-value")}, + input: NewObjectValueMust( + map[string]attr.Type{"test_attr": StringType{}}, + map[string]attr.Value{"test_attr": NewStringValue("test-value")}, ), - expected: map[string]attr.Type{"test_attr": StringType}, + expected: map[string]attr.Type{"test_attr": StringType{}}, }, "null": { - input: ObjectNull(map[string]attr.Type{"test_attr": StringType}), - expected: map[string]attr.Type{"test_attr": StringType}, + input: NewObjectNull(map[string]attr.Type{"test_attr": StringType{}}), + expected: map[string]attr.Type{"test_attr": StringType{}}, }, "unknown": { - input: ObjectUnknown(map[string]attr.Type{"test_attr": StringType}), - expected: map[string]attr.Type{"test_attr": StringType}, + input: NewObjectUnknown(map[string]attr.Type{"test_attr": StringType{}}), + expected: map[string]attr.Type{"test_attr": StringType{}}, }, } @@ -994,52 +994,52 @@ func TestObjectAttributeTypes(t *testing.T) { } } -func TestObjectToTerraformValue(t *testing.T) { +func TestObjectValueToTerraformValue(t *testing.T) { t.Parallel() type testCase struct { - receiver Object + receiver ObjectValue expected tftypes.Value expectedErr string } tests := map[string]testCase{ "value": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "a": ListType{ElemType: StringType}, - "b": StringType, - "c": BoolType, - "d": NumberType, + "a": ListType{ElemType: StringType{}}, + "b": StringType{}, + "c": BoolType{}, + "d": NumberType{}, "e": ObjectType{ AttrTypes: map[string]attr.Type{ - "name": StringType, + "name": StringType{}, }, }, - "f": SetType{ElemType: StringType}, + "f": SetType{ElemType: StringType{}}, }, map[string]attr.Value{ - "a": ListValueMust( - StringType, + "a": NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - "b": StringValue("woohoo"), - "c": BoolValue(true), - "d": NumberValue(big.NewFloat(1234)), - "e": ObjectValueMust( + "b": NewStringValue("woohoo"), + "c": NewBoolValue(true), + "d": NewNumberValue(big.NewFloat(1234)), + "e": NewObjectValueMust( map[string]attr.Type{ - "name": StringType, + "name": StringType{}, }, map[string]attr.Value{ - "name": StringValue("testing123"), + "name": NewStringValue("testing123"), }, ), - "f": SetValueMust( - StringType, + "f": NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), }, @@ -1075,18 +1075,18 @@ func TestObjectToTerraformValue(t *testing.T) { }), }, "unknown": { - receiver: ObjectUnknown( + receiver: NewObjectUnknown( map[string]attr.Type{ - "a": ListType{ElemType: StringType}, - "b": StringType, - "c": BoolType, - "d": NumberType, + "a": ListType{ElemType: StringType{}}, + "b": StringType{}, + "c": BoolType{}, + "d": NumberType{}, "e": ObjectType{ AttrTypes: map[string]attr.Type{ - "name": StringType, + "name": StringType{}, }, }, - "f": SetType{ElemType: StringType}, + "f": SetType{ElemType: StringType{}}, }, ), expected: tftypes.NewValue(tftypes.Object{ @@ -1105,18 +1105,18 @@ func TestObjectToTerraformValue(t *testing.T) { }, tftypes.UnknownValue), }, "null": { - receiver: ObjectNull( + receiver: NewObjectNull( map[string]attr.Type{ - "a": ListType{ElemType: StringType}, - "b": StringType, - "c": BoolType, - "d": NumberType, + "a": ListType{ElemType: StringType{}}, + "b": StringType{}, + "c": BoolType{}, + "d": NumberType{}, "e": ObjectType{ AttrTypes: map[string]attr.Type{ - "name": StringType, + "name": StringType{}, }, }, - "f": SetType{ElemType: StringType}, + "f": SetType{ElemType: StringType{}}, }, ), expected: tftypes.NewValue(tftypes.Object{ @@ -1135,43 +1135,43 @@ func TestObjectToTerraformValue(t *testing.T) { }, nil), }, "partial-unknown": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "a": ListType{ElemType: StringType}, - "b": StringType, - "c": BoolType, - "d": NumberType, + "a": ListType{ElemType: StringType{}}, + "b": StringType{}, + "c": BoolType{}, + "d": NumberType{}, "e": ObjectType{ AttrTypes: map[string]attr.Type{ - "name": StringType, + "name": StringType{}, }, }, - "f": SetType{ElemType: StringType}, + "f": SetType{ElemType: StringType{}}, }, map[string]attr.Value{ - "a": ListValueMust( - StringType, + "a": NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - "b": StringUnknown(), - "c": BoolValue(true), - "d": NumberValue(big.NewFloat(1234)), - "e": ObjectValueMust( + "b": NewStringUnknown(), + "c": NewBoolValue(true), + "d": NewNumberValue(big.NewFloat(1234)), + "e": NewObjectValueMust( map[string]attr.Type{ - "name": StringType, + "name": StringType{}, }, map[string]attr.Value{ - "name": StringValue("testing123"), + "name": NewStringValue("testing123"), }, ), - "f": SetValueMust( - StringType, + "f": NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), }, @@ -1211,43 +1211,43 @@ func TestObjectToTerraformValue(t *testing.T) { }), }, "partial-null": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "a": ListType{ElemType: StringType}, - "b": StringType, - "c": BoolType, - "d": NumberType, + "a": ListType{ElemType: StringType{}}, + "b": StringType{}, + "c": BoolType{}, + "d": NumberType{}, "e": ObjectType{ AttrTypes: map[string]attr.Type{ - "name": StringType, + "name": StringType{}, }, }, - "f": SetType{ElemType: StringType}, + "f": SetType{ElemType: StringType{}}, }, map[string]attr.Value{ - "a": ListValueMust( - StringType, + "a": NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - "b": StringNull(), - "c": BoolValue(true), - "d": NumberValue(big.NewFloat(1234)), - "e": ObjectValueMust( + "b": NewStringNull(), + "c": NewBoolValue(true), + "d": NewNumberValue(big.NewFloat(1234)), + "e": NewObjectValueMust( map[string]attr.Type{ - "name": StringType, + "name": StringType{}, }, map[string]attr.Value{ - "name": StringValue("testing123"), + "name": NewStringValue("testing123"), }, ), - "f": SetValueMust( - StringType, + "f": NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), }, @@ -1287,43 +1287,43 @@ func TestObjectToTerraformValue(t *testing.T) { }), }, "deep-partial-unknown": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "a": ListType{ElemType: StringType}, - "b": StringType, - "c": BoolType, - "d": NumberType, + "a": ListType{ElemType: StringType{}}, + "b": StringType{}, + "c": BoolType{}, + "d": NumberType{}, "e": ObjectType{ AttrTypes: map[string]attr.Type{ - "name": StringType, + "name": StringType{}, }, }, - "f": SetType{ElemType: StringType}, + "f": SetType{ElemType: StringType{}}, }, map[string]attr.Value{ - "a": ListValueMust( - StringType, + "a": NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - "b": StringValue("woohoo"), - "c": BoolValue(true), - "d": NumberValue(big.NewFloat(1234)), - "e": ObjectValueMust( + "b": NewStringValue("woohoo"), + "c": NewBoolValue(true), + "d": NewNumberValue(big.NewFloat(1234)), + "e": NewObjectValueMust( map[string]attr.Type{ - "name": StringType, + "name": StringType{}, }, map[string]attr.Value{ - "name": StringUnknown(), + "name": NewStringUnknown(), }, ), - "f": SetValueMust( - StringType, + "f": NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), }, @@ -1363,43 +1363,43 @@ func TestObjectToTerraformValue(t *testing.T) { }), }, "deep-partial-null": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "a": ListType{ElemType: StringType}, - "b": StringType, - "c": BoolType, - "d": NumberType, + "a": ListType{ElemType: StringType{}}, + "b": StringType{}, + "c": BoolType{}, + "d": NumberType{}, "e": ObjectType{ AttrTypes: map[string]attr.Type{ - "name": StringType, + "name": StringType{}, }, }, - "f": SetType{ElemType: StringType}, + "f": SetType{ElemType: StringType{}}, }, map[string]attr.Value{ - "a": ListValueMust( - StringType, + "a": NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - "b": StringValue("woohoo"), - "c": BoolValue(true), - "d": NumberValue(big.NewFloat(1234)), - "e": ObjectValueMust( + "b": NewStringValue("woohoo"), + "c": NewBoolValue(true), + "d": NewNumberValue(big.NewFloat(1234)), + "e": NewObjectValueMust( map[string]attr.Type{ - "name": StringType, + "name": StringType{}, }, map[string]attr.Value{ - "name": StringNull(), + "name": NewStringNull(), }, ), - "f": SetValueMust( - StringType, + "f": NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), }, @@ -1471,293 +1471,293 @@ func TestObjectToTerraformValue(t *testing.T) { } } -func TestObjectEqual(t *testing.T) { +func TestObjectValueEqual(t *testing.T) { t.Parallel() type testCase struct { - receiver Object + receiver ObjectValue arg attr.Value expected bool } tests := map[string]testCase{ "known-known": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, map[string]attr.Value{ - "string": StringValue("test"), - "bool": BoolValue(true), - "number": NumberValue(big.NewFloat(123)), + "string": NewStringValue("test"), + "bool": NewBoolValue(true), + "number": NewNumberValue(big.NewFloat(123)), }, ), - arg: ObjectValueMust( + arg: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, map[string]attr.Value{ - "string": StringValue("test"), - "bool": BoolValue(true), - "number": NumberValue(big.NewFloat(123)), + "string": NewStringValue("test"), + "bool": NewBoolValue(true), + "number": NewNumberValue(big.NewFloat(123)), }, ), expected: true, }, "known-known-diff-value": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, map[string]attr.Value{ - "string": StringValue("test"), - "bool": BoolValue(true), - "number": NumberValue(big.NewFloat(123)), + "string": NewStringValue("test"), + "bool": NewBoolValue(true), + "number": NewNumberValue(big.NewFloat(123)), }, ), - arg: ObjectValueMust( + arg: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, map[string]attr.Value{ - "string": StringValue("not-test"), - "bool": BoolValue(true), - "number": NumberValue(big.NewFloat(123)), + "string": NewStringValue("not-test"), + "bool": NewBoolValue(true), + "number": NewNumberValue(big.NewFloat(123)), }, ), expected: false, }, "known-known-diff-attribute-types": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, + "string": StringType{}, }, map[string]attr.Value{ - "string": StringValue("hello"), + "string": NewStringValue("hello"), }, ), - arg: ObjectValueMust( + arg: NewObjectValueMust( map[string]attr.Type{ - "number": NumberType, + "number": NumberType{}, }, map[string]attr.Value{ - "number": NumberValue(big.NewFloat(123)), + "number": NewNumberValue(big.NewFloat(123)), }, ), expected: false, }, "known-known-diff-unknown": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, + "string": StringType{}, }, map[string]attr.Value{ - "string": StringValue("hello"), + "string": NewStringValue("hello"), }, ), - arg: ObjectValueMust( + arg: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, + "string": StringType{}, }, map[string]attr.Value{ - "string": StringUnknown(), + "string": NewStringUnknown(), }, ), expected: false, }, "known-known-diff-null": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, + "string": StringType{}, }, map[string]attr.Value{ - "string": StringValue("hello"), + "string": NewStringValue("hello"), }, ), - arg: ObjectValueMust( + arg: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, + "string": StringType{}, }, map[string]attr.Value{ - "string": StringNull(), + "string": NewStringNull(), }, ), expected: false, }, "known-unknown": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, map[string]attr.Value{ - "string": StringValue("hello"), - "bool": BoolValue(true), - "number": NumberValue(big.NewFloat(123)), + "string": NewStringValue("hello"), + "bool": NewBoolValue(true), + "number": NewNumberValue(big.NewFloat(123)), }, ), - arg: ObjectUnknown( + arg: NewObjectUnknown( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, ), expected: false, }, "known-null": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, map[string]attr.Value{ - "string": StringValue("hello"), - "bool": BoolValue(true), - "number": NumberValue(big.NewFloat(123)), + "string": NewStringValue("hello"), + "bool": NewBoolValue(true), + "number": NewNumberValue(big.NewFloat(123)), }, ), - arg: ObjectNull( + arg: NewObjectNull( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, ), expected: false, }, "known-diff-wrong-type": { - receiver: ObjectValueMust( + receiver: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, map[string]attr.Value{ - "string": StringValue("hello"), - "bool": BoolValue(true), - "number": NumberValue(big.NewFloat(123)), + "string": NewStringValue("hello"), + "bool": NewBoolValue(true), + "number": NewNumberValue(big.NewFloat(123)), }, ), - arg: StringValue("whoops"), + arg: NewStringValue("whoops"), expected: false, }, "unknown-known": { - receiver: ObjectUnknown( + receiver: NewObjectUnknown( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, ), - arg: ObjectValueMust( + arg: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, map[string]attr.Value{ - "string": StringValue("hello"), - "bool": BoolValue(true), - "number": NumberValue(big.NewFloat(123)), + "string": NewStringValue("hello"), + "bool": NewBoolValue(true), + "number": NewNumberValue(big.NewFloat(123)), }, ), expected: false, }, "unknown-unknown": { - receiver: ObjectUnknown( + receiver: NewObjectUnknown( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, ), - arg: ObjectUnknown( + arg: NewObjectUnknown( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, ), expected: true, }, "unknown-null": { - receiver: ObjectUnknown( + receiver: NewObjectUnknown( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, ), - arg: ObjectNull( + arg: NewObjectNull( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, ), expected: false, }, "null-known": { - receiver: ObjectNull( + receiver: NewObjectNull( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, ), - arg: ObjectValueMust( + arg: NewObjectValueMust( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, map[string]attr.Value{ - "string": StringValue("hello"), - "bool": BoolValue(true), - "number": NumberValue(big.NewFloat(123)), + "string": NewStringValue("hello"), + "bool": NewBoolValue(true), + "number": NewNumberValue(big.NewFloat(123)), }, ), expected: false, }, "null-unknown": { - receiver: ObjectNull( + receiver: NewObjectNull( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, ), - arg: ObjectUnknown( + arg: NewObjectUnknown( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, ), expected: false, }, "null-null": { - receiver: ObjectNull( + receiver: NewObjectNull( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, ), - arg: ObjectNull( + arg: NewObjectNull( map[string]attr.Type{ - "string": StringType, - "bool": BoolType, - "number": NumberType, + "string": StringType{}, + "bool": BoolType{}, + "number": NumberType{}, }, ), expected: true, @@ -1777,26 +1777,26 @@ func TestObjectEqual(t *testing.T) { } } -func TestObjectIsNull(t *testing.T) { +func TestObjectValueIsNull(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Object + input ObjectValue expected bool }{ "known": { - input: ObjectValueMust( - map[string]attr.Type{"test_attr": StringType}, - map[string]attr.Value{"test_attr": StringValue("test-value")}, + input: NewObjectValueMust( + map[string]attr.Type{"test_attr": StringType{}}, + map[string]attr.Value{"test_attr": NewStringValue("test-value")}, ), expected: false, }, "null": { - input: ObjectNull(map[string]attr.Type{"test_attr": StringType}), + input: NewObjectNull(map[string]attr.Type{"test_attr": StringType{}}), expected: true, }, "unknown": { - input: ObjectUnknown(map[string]attr.Type{"test_attr": StringType}), + input: NewObjectUnknown(map[string]attr.Type{"test_attr": StringType{}}), expected: false, }, } @@ -1816,26 +1816,26 @@ func TestObjectIsNull(t *testing.T) { } } -func TestObjectIsUnknown(t *testing.T) { +func TestObjectValueIsUnknown(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Object + input ObjectValue expected bool }{ "known": { - input: ObjectValueMust( - map[string]attr.Type{"test_attr": StringType}, - map[string]attr.Value{"test_attr": StringValue("test-value")}, + input: NewObjectValueMust( + map[string]attr.Type{"test_attr": StringType{}}, + map[string]attr.Value{"test_attr": NewStringValue("test-value")}, ), expected: false, }, "null": { - input: ObjectNull(map[string]attr.Type{"test_attr": StringType}), + input: NewObjectNull(map[string]attr.Type{"test_attr": StringType{}}), expected: false, }, "unknown": { - input: ObjectUnknown(map[string]attr.Type{"test_attr": StringType}), + input: NewObjectUnknown(map[string]attr.Type{"test_attr": StringType{}}), expected: true, }, } @@ -1855,96 +1855,96 @@ func TestObjectIsUnknown(t *testing.T) { } } -func TestObjectString(t *testing.T) { +func TestObjectValueString(t *testing.T) { t.Parallel() type testCase struct { - input Object + input ObjectValue expectation string } tests := map[string]testCase{ "known": { - input: ObjectValueMust( + input: NewObjectValueMust( map[string]attr.Type{ - "alpha": StringType, - "beta": Int64Type, - "gamma": Float64Type, - "sigma": NumberType, - "theta": BoolType, + "alpha": StringType{}, + "beta": Int64Type{}, + "gamma": Float64Type{}, + "sigma": NumberType{}, + "theta": BoolType{}, }, map[string]attr.Value{ - "alpha": StringValue("hello"), - "beta": Int64Value(98719827987189), - "gamma": Float64Value(-9876.782378), - "sigma": NumberUnknown(), - "theta": BoolNull(), + "alpha": NewStringValue("hello"), + "beta": NewInt64Value(98719827987189), + "gamma": NewFloat64Value(-9876.782378), + "sigma": NewNumberUnknown(), + "theta": NewBoolNull(), }, ), expectation: `{"alpha":"hello","beta":98719827987189,"gamma":-9876.782378,"sigma":,"theta":}`, }, "known-object-of-objects": { - input: ObjectValueMust( + input: NewObjectValueMust( map[string]attr.Type{ "alpha": ObjectType{ AttrTypes: map[string]attr.Type{ - "one": StringType, - "two": BoolType, - "three": NumberType, + "one": StringType{}, + "two": BoolType{}, + "three": NumberType{}, }, }, "beta": ObjectType{ AttrTypes: map[string]attr.Type{ - "uno": Int64Type, - "due": BoolType, - "tre": StringType, + "uno": Int64Type{}, + "due": BoolType{}, + "tre": StringType{}, }, }, - "gamma": Float64Type, - "sigma": NumberType, - "theta": BoolType, + "gamma": Float64Type{}, + "sigma": NumberType{}, + "theta": BoolType{}, }, map[string]attr.Value{ - "alpha": ObjectValueMust( + "alpha": NewObjectValueMust( map[string]attr.Type{ - "one": StringType, - "two": BoolType, - "three": NumberType, + "one": StringType{}, + "two": BoolType{}, + "three": NumberType{}, }, map[string]attr.Value{ - "one": StringValue("1"), - "two": BoolValue(true), - "three": NumberValue(big.NewFloat(0.3)), + "one": NewStringValue("1"), + "two": NewBoolValue(true), + "three": NewNumberValue(big.NewFloat(0.3)), }, ), - "beta": ObjectValueMust( + "beta": NewObjectValueMust( map[string]attr.Type{ - "uno": Int64Type, - "due": BoolType, - "tre": StringType, + "uno": Int64Type{}, + "due": BoolType{}, + "tre": StringType{}, }, map[string]attr.Value{ - "uno": Int64Value(1), - "due": BoolValue(false), - "tre": StringValue("3"), + "uno": NewInt64Value(1), + "due": NewBoolValue(false), + "tre": NewStringValue("3"), }, ), - "gamma": Float64Value(-9876.782378), - "sigma": NumberUnknown(), - "theta": BoolNull(), + "gamma": NewFloat64Value(-9876.782378), + "sigma": NewNumberUnknown(), + "theta": NewBoolNull(), }, ), expectation: `{"alpha":{"one":"1","three":0.3,"two":true},"beta":{"due":false,"tre":"3","uno":1},"gamma":-9876.782378,"sigma":,"theta":}`, }, "unknown": { - input: ObjectUnknown(map[string]attr.Type{"test_attr": StringType}), + input: NewObjectUnknown(map[string]attr.Type{"test_attr": StringType{}}), expectation: "", }, "null": { - input: ObjectNull(map[string]attr.Type{"test_attr": StringType}), + input: NewObjectNull(map[string]attr.Type{"test_attr": StringType{}}), expectation: "", }, "zero-value": { - input: Object{}, + input: ObjectValue{}, expectation: "", }, } @@ -1962,67 +1962,67 @@ func TestObjectString(t *testing.T) { } } -func TestObjectType(t *testing.T) { +func TestObjectValueType(t *testing.T) { t.Parallel() type testCase struct { - input Object + input ObjectValue expectation attr.Type } tests := map[string]testCase{ "known": { - input: ObjectValueMust( + input: NewObjectValueMust( map[string]attr.Type{ - "test_attr1": StringType, - "test_attr2": StringType, + "test_attr1": StringType{}, + "test_attr2": StringType{}, }, map[string]attr.Value{ - "test_attr1": StringValue("hello"), - "test_attr2": StringValue("world"), + "test_attr1": NewStringValue("hello"), + "test_attr2": NewStringValue("world"), }, ), expectation: ObjectType{ AttrTypes: map[string]attr.Type{ - "test_attr1": StringType, - "test_attr2": StringType, + "test_attr1": StringType{}, + "test_attr2": StringType{}, }, }, }, "known-object-of-objects": { - input: ObjectValueMust( + input: NewObjectValueMust( map[string]attr.Type{ "test_attr1": ObjectType{ AttrTypes: map[string]attr.Type{ - "test_attr1": StringType, - "test_attr2": StringType, + "test_attr1": StringType{}, + "test_attr2": StringType{}, }, }, "test_attr2": ObjectType{ AttrTypes: map[string]attr.Type{ - "test_attr1": StringType, - "test_attr2": StringType, + "test_attr1": StringType{}, + "test_attr2": StringType{}, }, }, }, map[string]attr.Value{ - "test_attr1": ObjectValueMust( + "test_attr1": NewObjectValueMust( map[string]attr.Type{ - "test_attr1": StringType, - "test_attr2": StringType, + "test_attr1": StringType{}, + "test_attr2": StringType{}, }, map[string]attr.Value{ - "test_attr1": StringValue("hello"), - "test_attr2": StringValue("world"), + "test_attr1": NewStringValue("hello"), + "test_attr2": NewStringValue("world"), }, ), - "test_attr2": ObjectValueMust( + "test_attr2": NewObjectValueMust( map[string]attr.Type{ - "test_attr1": StringType, - "test_attr2": StringType, + "test_attr1": StringType{}, + "test_attr2": StringType{}, }, map[string]attr.Value{ - "test_attr1": StringValue("foo"), - "test_attr2": StringValue("bar"), + "test_attr1": NewStringValue("foo"), + "test_attr2": NewStringValue("bar"), }, ), }, @@ -2031,26 +2031,26 @@ func TestObjectType(t *testing.T) { AttrTypes: map[string]attr.Type{ "test_attr1": ObjectType{ AttrTypes: map[string]attr.Type{ - "test_attr1": StringType, - "test_attr2": StringType, + "test_attr1": StringType{}, + "test_attr2": StringType{}, }, }, "test_attr2": ObjectType{ AttrTypes: map[string]attr.Type{ - "test_attr1": StringType, - "test_attr2": StringType, + "test_attr1": StringType{}, + "test_attr2": StringType{}, }, }, }, }, }, "unknown": { - input: ObjectUnknown(map[string]attr.Type{"test_attr": StringType}), - expectation: ObjectType{AttrTypes: map[string]attr.Type{"test_attr": StringType}}, + input: NewObjectUnknown(map[string]attr.Type{"test_attr": StringType{}}), + expectation: ObjectType{AttrTypes: map[string]attr.Type{"test_attr": StringType{}}}, }, "null": { - input: ObjectNull(map[string]attr.Type{"test_attr": StringType}), - expectation: ObjectType{AttrTypes: map[string]attr.Type{"test_attr": StringType}}, + input: NewObjectNull(map[string]attr.Type{"test_attr": StringType{}}), + expectation: ObjectType{AttrTypes: map[string]attr.Type{"test_attr": StringType{}}}, }, } diff --git a/types/pointer_test.go b/types/basetypes/pointer_test.go similarity index 74% rename from types/pointer_test.go rename to types/basetypes/pointer_test.go index 627bd9a52..97e87e6be 100644 --- a/types/pointer_test.go +++ b/types/basetypes/pointer_test.go @@ -1,4 +1,4 @@ -package types +package basetypes func pointer[T any](value T) *T { return &value diff --git a/types/set.go b/types/basetypes/set.go similarity index 84% rename from types/set.go rename to types/basetypes/set.go index c135675c7..5ffb88163 100644 --- a/types/set.go +++ b/types/basetypes/set.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -17,7 +17,7 @@ import ( var ( _ SetTypable = SetType{} _ xattr.TypeWithValidate = SetType{} - _ SetValuable = &Set{} + _ SetValuable = &SetValue{} ) // SetTypable extends attr.Type for set types. @@ -26,7 +26,7 @@ type SetTypable interface { attr.Type // ValueFromSet should convert the Set to a SetValuable type. - ValueFromSet(context.Context, Set) (SetValuable, diag.Diagnostics) + ValueFromSet(context.Context, SetValue) (SetValuable, diag.Diagnostics) } // SetValuable extends attr.Value for set value types. @@ -35,7 +35,7 @@ type SetValuable interface { attr.Value // ToSetValue should convert the value type to a Set. - ToSetValue(ctx context.Context) (Set, diag.Diagnostics) + ToSetValue(ctx context.Context) (SetValue, diag.Diagnostics) } // SetType is an AttributeType representing a set of values. All values must @@ -72,16 +72,16 @@ func (st SetType) TerraformType(ctx context.Context) tftypes.Type { // type for the provider to consume the data with. func (st SetType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { if in.Type() == nil { - return SetNull(st.ElemType), nil + return NewSetNull(st.ElemType), nil } if !in.Type().Equal(st.TerraformType(ctx)) { return nil, fmt.Errorf("can't use %s as value of Set with ElementType %T, can only use %s values", in.String(), st.ElemType, st.ElemType.TerraformType(ctx).String()) } if !in.IsKnown() { - return SetUnknown(st.ElemType), nil + return NewSetUnknown(st.ElemType), nil } if in.IsNull() { - return SetNull(st.ElemType), nil + return NewSetNull(st.ElemType), nil } val := []tftypes.Value{} err := in.As(&val) @@ -98,7 +98,7 @@ func (st SetType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (att } // ValueFromTerraform above on each element should make this safe. // Otherwise, this will need to do some Diagnostics to error conversion. - return SetValueMust(st.ElemType, elems), nil + return NewSetValueMust(st.ElemType, elems), nil } // Equal returns true if `o` is also a SetType and has the same ElemType. @@ -210,37 +210,37 @@ func (st SetType) Validate(ctx context.Context, in tftypes.Value, path path.Path // ValueType returns the Value type. func (st SetType) ValueType(_ context.Context) attr.Value { - return Set{ + return SetValue{ elementType: st.ElemType, } } // ValueFromSet returns a SetValuable type given a Set. -func (st SetType) ValueFromSet(_ context.Context, set Set) (SetValuable, diag.Diagnostics) { +func (st SetType) ValueFromSet(_ context.Context, set SetValue) (SetValuable, diag.Diagnostics) { return set, nil } -// SetNull creates a Set with a null value. Determine whether the value is +// NewSetNull creates a Set with a null value. Determine whether the value is // null via the Set type IsNull method. -func SetNull(elementType attr.Type) Set { - return Set{ +func NewSetNull(elementType attr.Type) SetValue { + return SetValue{ elementType: elementType, state: attr.ValueStateNull, } } -// SetUnknown creates a Set with an unknown value. Determine whether the +// NewSetUnknown creates a Set with an unknown value. Determine whether the // value is unknown via the Set type IsUnknown method. -func SetUnknown(elementType attr.Type) Set { - return Set{ +func NewSetUnknown(elementType attr.Type) SetValue { + return SetValue{ elementType: elementType, state: attr.ValueStateUnknown, } } -// SetValue creates a Set with a known value. Access the value via the Set +// NewSetValue creates a Set with a known value. Access the value via the Set // type Elements or ElementsAs methods. -func SetValue(elementType attr.Type, elements []attr.Value) (Set, diag.Diagnostics) { +func NewSetValue(elementType attr.Type, elements []attr.Value) (SetValue, diag.Diagnostics) { var diags diag.Diagnostics // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 @@ -260,20 +260,20 @@ func SetValue(elementType attr.Type, elements []attr.Value) (Set, diag.Diagnosti } if diags.HasError() { - return SetUnknown(elementType), diags + return NewSetUnknown(elementType), diags } - return Set{ + return SetValue{ elementType: elementType, elements: elements, state: attr.ValueStateKnown, }, nil } -// SetValueFrom creates a Set with a known value, using reflection rules. +// NewSetValueFrom creates a Set with a known value, using reflection rules. // The elements must be a slice which can convert into the given element type. // Access the value via the Set type Elements or ElementsAs methods. -func SetValueFrom(ctx context.Context, elementType attr.Type, elements any) (Set, diag.Diagnostics) { +func NewSetValueFrom(ctx context.Context, elementType attr.Type, elements any) (SetValue, diag.Diagnostics) { attrValue, diags := reflect.FromValue( ctx, SetType{ElemType: elementType}, @@ -282,10 +282,10 @@ func SetValueFrom(ctx context.Context, elementType attr.Type, elements any) (Set ) if diags.HasError() { - return SetUnknown(elementType), diags + return NewSetUnknown(elementType), diags } - set, ok := attrValue.(Set) + set, ok := attrValue.(SetValue) // This should not happen, but ensure there is an error if it does. if !ok { @@ -299,15 +299,15 @@ func SetValueFrom(ctx context.Context, elementType attr.Type, elements any) (Set return set, diags } -// SetValueMust creates a Set with a known value, converting any diagnostics +// NewSetValueMust creates a Set with a known value, converting any diagnostics // into a panic at runtime. Access the value via the Set // type Elements or ElementsAs methods. // // This creation function is only recommended to create Set values which will // not potentially effect practitioners, such as testing, or exhaustively // tested provider logic. -func SetValueMust(elementType attr.Type, elements []attr.Value) Set { - set, diags := SetValue(elementType, elements) +func NewSetValueMust(elementType attr.Type, elements []attr.Value) SetValue { + set, diags := NewSetValue(elementType, elements) if diags.HasError() { // This could potentially be added to the diag package. @@ -327,9 +327,9 @@ func SetValueMust(elementType attr.Type, elements []attr.Value) Set { return set } -// Set represents a set of attr.Value, all of the same type, +// SetValue represents a set of attr.Value, all of the same type, // indicated by ElemType. -type Set struct { +type SetValue struct { // elements is the collection of known values in the Set. elements []attr.Value @@ -343,13 +343,13 @@ type Set struct { // Elements returns the collection of elements for the Set. Returns nil if the // Set is null or unknown. -func (s Set) Elements() []attr.Value { +func (s SetValue) Elements() []attr.Value { return s.elements } -// ElementsAs populates `target` with the elements of the Set, throwing an +// ElementsAs populates `target` with the elements of the SetValue, throwing an // error if the elements cannot be stored in `target`. -func (s Set) ElementsAs(ctx context.Context, target interface{}, allowUnhandled bool) diag.Diagnostics { +func (s SetValue) ElementsAs(ctx context.Context, target interface{}, allowUnhandled bool) diag.Diagnostics { // we need a tftypes.Value for this Set to be able to use it with our // reflection code val, err := s.ToTerraformValue(ctx) @@ -368,17 +368,17 @@ func (s Set) ElementsAs(ctx context.Context, target interface{}, allowUnhandled } // ElementType returns the element type for the Set. -func (s Set) ElementType(_ context.Context) attr.Type { +func (s SetValue) ElementType(_ context.Context) attr.Type { return s.elementType } // Type returns a SetType with the same element type as `s`. -func (s Set) Type(ctx context.Context) attr.Type { +func (s SetValue) Type(ctx context.Context) attr.Type { return SetType{ElemType: s.ElementType(ctx)} } // ToTerraformValue returns the data contained in the Set as a tftypes.Value. -func (s Set) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { +func (s SetValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { setType := tftypes.Set{ElementType: s.ElementType(ctx).TerraformType(ctx)} switch s.state { @@ -411,8 +411,8 @@ func (s Set) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { // Equal returns true if the Set is considered semantically equal // (same type and same value) to the attr.Value passed as an argument. -func (s Set) Equal(o attr.Value) bool { - other, ok := o.(Set) +func (s SetValue) Equal(o attr.Value) bool { + other, ok := o.(SetValue) if !ok { return false @@ -443,7 +443,7 @@ func (s Set) Equal(o attr.Value) bool { return true } -func (s Set) contains(v attr.Value) bool { +func (s SetValue) contains(v attr.Value) bool { for _, elem := range s.Elements() { if elem.Equal(v) { return true @@ -454,21 +454,21 @@ func (s Set) contains(v attr.Value) bool { } // IsNull returns true if the Set represents a null value. -func (s Set) IsNull() bool { +func (s SetValue) IsNull() bool { return s.state == attr.ValueStateNull } // IsUnknown returns true if the Set represents a currently unknown value. // Returns false if the Set has a known number of elements, even if all are // unknown values. -func (s Set) IsUnknown() bool { +func (s SetValue) IsUnknown() bool { return s.state == attr.ValueStateUnknown } // String returns a human-readable representation of the Set value. // The string returned here is not protected by any compatibility guarantees, // and is intended for logging and error reporting. -func (s Set) String() string { +func (s SetValue) String() string { if s.IsUnknown() { return attr.UnknownValueString } @@ -492,6 +492,6 @@ func (s Set) String() string { } // ToSetValue returns the Set. -func (s Set) ToSetValue(context.Context) (Set, diag.Diagnostics) { +func (s SetValue) ToSetValue(context.Context) (SetValue, diag.Diagnostics) { return s, nil } diff --git a/types/set_test.go b/types/basetypes/set_test.go similarity index 72% rename from types/set_test.go rename to types/basetypes/set_test.go index 56cd4c633..6cf618abd 100644 --- a/types/set_test.go +++ b/types/basetypes/set_test.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -22,7 +22,7 @@ func TestSetTypeTerraformType(t *testing.T) { tests := map[string]testCase{ "set-of-strings": { input: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, expected: tftypes.Set{ ElementType: tftypes.String, @@ -31,7 +31,7 @@ func TestSetTypeTerraformType(t *testing.T) { "set-of-set-of-strings": { input: SetType{ ElemType: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, }, expected: tftypes.Set{ @@ -44,7 +44,7 @@ func TestSetTypeTerraformType(t *testing.T) { input: SetType{ ElemType: SetType{ ElemType: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, }, }, @@ -82,7 +82,7 @@ func TestSetTypeValueFromTerraform(t *testing.T) { tests := map[string]testCase{ "set-of-strings": { receiver: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.Set{ ElementType: tftypes.String, @@ -90,17 +90,17 @@ func TestSetTypeValueFromTerraform(t *testing.T) { tftypes.NewValue(tftypes.String, "hello"), tftypes.NewValue(tftypes.String, "world"), }), - expected: SetValueMust( - StringType, + expected: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), }, "set-of-duplicate-strings": { receiver: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.Set{ ElementType: tftypes.String, @@ -110,26 +110,26 @@ func TestSetTypeValueFromTerraform(t *testing.T) { }), // Duplicate validation does not occur during this method. // This is okay, as tftypes allows duplicates. - expected: SetValueMust( - StringType, + expected: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("hello"), + NewStringValue("hello"), + NewStringValue("hello"), }, ), }, "unknown-set": { receiver: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.Set{ ElementType: tftypes.String, }, tftypes.UnknownValue), - expected: SetUnknown(StringType), + expected: NewSetUnknown(StringType{}), }, "partially-unknown-set": { receiver: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.Set{ ElementType: tftypes.String, @@ -137,26 +137,26 @@ func TestSetTypeValueFromTerraform(t *testing.T) { tftypes.NewValue(tftypes.String, "hello"), tftypes.NewValue(tftypes.String, tftypes.UnknownValue), }), - expected: SetValueMust( - StringType, + expected: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringUnknown(), + NewStringValue("hello"), + NewStringUnknown(), }, ), }, "null-set": { receiver: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.Set{ ElementType: tftypes.String, }, nil), - expected: SetNull(StringType), + expected: NewSetNull(StringType{}), }, "partially-null-set": { receiver: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.Set{ ElementType: tftypes.String, @@ -164,38 +164,38 @@ func TestSetTypeValueFromTerraform(t *testing.T) { tftypes.NewValue(tftypes.String, "hello"), tftypes.NewValue(tftypes.String, nil), }), - expected: SetValueMust( - StringType, + expected: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringNull(), + NewStringValue("hello"), + NewStringNull(), }, ), }, "wrong-type": { receiver: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.String, "wrong"), - expectedErr: `can't use tftypes.String<"wrong"> as value of Set with ElementType types.primitive, can only use tftypes.String values`, + expectedErr: `can't use tftypes.String<"wrong"> as value of Set with ElementType basetypes.StringType, can only use tftypes.String values`, }, "wrong-element-type": { receiver: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(tftypes.Set{ ElementType: tftypes.Number, }, []tftypes.Value{ tftypes.NewValue(tftypes.Number, 1), }), - expectedErr: `can't use tftypes.Set[tftypes.Number]> as value of Set with ElementType types.primitive, can only use tftypes.String values`, + expectedErr: `can't use tftypes.Set[tftypes.Number]> as value of Set with ElementType basetypes.StringType, can only use tftypes.String values`, }, "nil-type": { receiver: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, input: tftypes.NewValue(nil, nil), - expected: SetNull(StringType), + expected: NewSetNull(StringType{}), }, } for name, test := range tests { @@ -241,22 +241,22 @@ func TestSetTypeEqual(t *testing.T) { } tests := map[string]testCase{ "equal": { - receiver: SetType{ElemType: StringType}, - input: SetType{ElemType: StringType}, + receiver: SetType{ElemType: StringType{}}, + input: SetType{ElemType: StringType{}}, expected: true, }, "diff": { - receiver: SetType{ElemType: StringType}, - input: SetType{ElemType: NumberType}, + receiver: SetType{ElemType: StringType{}}, + input: SetType{ElemType: NumberType{}}, expected: false, }, "wrongType": { - receiver: SetType{ElemType: StringType}, - input: NumberType, + receiver: SetType{ElemType: StringType{}}, + input: NumberType{}, expected: false, }, "nil": { - receiver: SetType{ElemType: StringType}, + receiver: SetType{ElemType: StringType{}}, input: nil, expected: false, }, @@ -287,11 +287,11 @@ func TestSetElementsAs_stringSlice(t *testing.T) { var stringSlice []string expected := []string{"hello", "world"} - diags := SetValueMust( - StringType, + diags := NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ).ElementsAs(context.Background(), &stringSlice, false) if diags.HasError() { @@ -305,17 +305,17 @@ func TestSetElementsAs_stringSlice(t *testing.T) { func TestSetElementsAs_attributeValueSlice(t *testing.T) { t.Parallel() - var stringSlice []String - expected := []String{ - StringValue("hello"), - StringValue("world"), + var stringSlice []StringValue + expected := []StringValue{ + NewStringValue("hello"), + NewStringValue("world"), } - diags := SetValueMust( - StringType, + diags := NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ).ElementsAs(context.Background(), &stringSlice, false) if diags.HasError() { @@ -563,51 +563,51 @@ func TestSetTypeValidate(t *testing.T) { } } -func TestSetValue(t *testing.T) { +func TestNewSetValue(t *testing.T) { t.Parallel() testCases := map[string]struct { elementType attr.Type elements []attr.Value - expected Set + expected SetValue expectedDiags diag.Diagnostics }{ "valid-no-elements": { - elementType: StringType, + elementType: StringType{}, elements: []attr.Value{}, - expected: SetValueMust(StringType, []attr.Value{}), + expected: NewSetValueMust(StringType{}, []attr.Value{}), }, "valid-elements": { - elementType: StringType, + elementType: StringType{}, elements: []attr.Value{ - StringNull(), - StringUnknown(), - StringValue("test"), + NewStringNull(), + NewStringUnknown(), + NewStringValue("test"), }, - expected: SetValueMust( - StringType, + expected: NewSetValueMust( + StringType{}, []attr.Value{ - StringNull(), - StringUnknown(), - StringValue("test"), + NewStringNull(), + NewStringUnknown(), + NewStringValue("test"), }, ), }, "invalid-element-type": { - elementType: StringType, + elementType: StringType{}, elements: []attr.Value{ - StringValue("test"), - BoolValue(true), + NewStringValue("test"), + NewBoolValue(true), }, - expected: SetUnknown(StringType), + expected: NewSetUnknown(StringType{}), expectedDiags: diag.Diagnostics{ diag.NewErrorDiagnostic( "Invalid Set Element Type", "While creating a Set value, an invalid element was detected. "+ "A Set must use the single, given element type. "+ "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ - "Set Element Type: types.StringType\n"+ - "Set Index (1) Element Type: types.BoolType", + "Set Element Type: basetypes.StringType\n"+ + "Set Index (1) Element Type: basetypes.BoolType", ), }, }, @@ -619,7 +619,7 @@ func TestSetValue(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - got, diags := SetValue(testCase.elementType, testCase.elements) + got, diags := NewSetValue(testCase.elementType, testCase.elements) if diff := cmp.Diff(got, testCase.expected); diff != "" { t.Errorf("unexpected difference: %s", diff) @@ -632,81 +632,81 @@ func TestSetValue(t *testing.T) { } } -func TestSetValueFrom(t *testing.T) { +func TestNewSetValueFrom(t *testing.T) { t.Parallel() testCases := map[string]struct { elementType attr.Type elements any - expected Set + expected SetValue expectedDiags diag.Diagnostics }{ - "valid-StringType-[]attr.Value-empty": { - elementType: StringType, + "valid-StringType{}-[]attr.Value-empty": { + elementType: StringType{}, elements: []attr.Value{}, - expected: SetValueMust( - StringType, + expected: NewSetValueMust( + StringType{}, []attr.Value{}, ), }, - "valid-StringType-[]types.String-empty": { - elementType: StringType, - elements: []String{}, - expected: SetValueMust( - StringType, + "valid-StringType{}-[]types.String-empty": { + elementType: StringType{}, + elements: []StringValue{}, + expected: NewSetValueMust( + StringType{}, []attr.Value{}, ), }, - "valid-StringType-[]types.String": { - elementType: StringType, - elements: []String{ - StringNull(), - StringUnknown(), - StringValue("test"), + "valid-StringType{}-[]types.String": { + elementType: StringType{}, + elements: []StringValue{ + NewStringNull(), + NewStringUnknown(), + NewStringValue("test"), }, - expected: SetValueMust( - StringType, + expected: NewSetValueMust( + StringType{}, []attr.Value{ - StringNull(), - StringUnknown(), - StringValue("test"), + NewStringNull(), + NewStringUnknown(), + NewStringValue("test"), }, ), }, - "valid-StringType-[]*string": { - elementType: StringType, + "valid-StringType{}-[]*string": { + elementType: StringType{}, elements: []*string{ nil, pointer("test1"), pointer("test2"), }, - expected: SetValueMust( - StringType, + expected: NewSetValueMust( + StringType{}, []attr.Value{ - StringNull(), - StringValue("test1"), - StringValue("test2"), + NewStringNull(), + NewStringValue("test1"), + NewStringValue("test2"), }, ), }, - "valid-StringType-[]string": { - elementType: StringType, + "valid-StringType{}-[]string": { + elementType: StringType{}, elements: []string{ "test1", "test2", }, - expected: SetValueMust( - StringType, + expected: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("test1"), - StringValue("test2"), + NewStringValue("test1"), + NewStringValue("test2"), }, ), }, "invalid-not-slice": { - elementType: StringType, + elementType: StringType{}, elements: "oops", - expected: SetUnknown(StringType), + expected: NewSetUnknown(StringType{}), expectedDiags: diag.Diagnostics{ diag.NewAttributeErrorDiagnostic( path.Empty(), @@ -717,9 +717,9 @@ func TestSetValueFrom(t *testing.T) { }, }, "invalid-type": { - elementType: StringType, + elementType: StringType{}, elements: []bool{true}, - expected: SetUnknown(StringType), + expected: NewSetUnknown(StringType{}), expectedDiags: diag.Diagnostics{ diag.NewAttributeErrorDiagnostic( path.Empty().AtListIndex(0), @@ -737,7 +737,7 @@ func TestSetValueFrom(t *testing.T) { t.Run(name, func(t *testing.T) { t.Parallel() - got, diags := SetValueFrom(context.Background(), testCase.elementType, testCase.elements) + got, diags := NewSetValueFrom(context.Background(), testCase.elementType, testCase.elements) if diff := cmp.Diff(got, testCase.expected); diff != "" { t.Errorf("unexpected difference: %s", diff) @@ -750,21 +750,21 @@ func TestSetValueFrom(t *testing.T) { } } -func TestSetToTerraformValue(t *testing.T) { +func TestSetValueToTerraformValue(t *testing.T) { t.Parallel() type testCase struct { - input Set + input SetValue expectation tftypes.Value expectedErr string } tests := map[string]testCase{ "known": { - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expectation: tftypes.NewValue(tftypes.Set{ElementType: tftypes.String}, []tftypes.Value{ @@ -773,11 +773,11 @@ func TestSetToTerraformValue(t *testing.T) { }), }, "known-duplicates": { - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("hello"), + NewStringValue("hello"), + NewStringValue("hello"), }, ), // Duplicate validation does not occur during this method. @@ -788,11 +788,11 @@ func TestSetToTerraformValue(t *testing.T) { }), }, "known-partial-unknown": { - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringUnknown(), - StringValue("hello, world"), + NewStringUnknown(), + NewStringValue("hello, world"), }, ), expectation: tftypes.NewValue(tftypes.Set{ElementType: tftypes.String}, []tftypes.Value{ @@ -801,11 +801,11 @@ func TestSetToTerraformValue(t *testing.T) { }), }, "known-partial-null": { - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringNull(), - StringValue("hello, world"), + NewStringNull(), + NewStringValue("hello, world"), }, ), expectation: tftypes.NewValue(tftypes.Set{ElementType: tftypes.String}, []tftypes.Value{ @@ -814,11 +814,11 @@ func TestSetToTerraformValue(t *testing.T) { }), }, "unknown": { - input: SetUnknown(StringType), + input: NewSetUnknown(StringType{}), expectation: tftypes.NewValue(tftypes.Set{ElementType: tftypes.String}, tftypes.UnknownValue), }, "null": { - input: SetNull(StringType), + input: NewSetNull(StringType{}), expectation: tftypes.NewValue(tftypes.Set{ElementType: tftypes.String}, nil), }, } @@ -853,23 +853,23 @@ func TestSetToTerraformValue(t *testing.T) { } } -func TestSetElements(t *testing.T) { +func TestSetValueElements(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Set + input SetValue expected []attr.Value }{ "known": { - input: SetValueMust(StringType, []attr.Value{StringValue("test")}), - expected: []attr.Value{StringValue("test")}, + input: NewSetValueMust(StringType{}, []attr.Value{NewStringValue("test")}), + expected: []attr.Value{NewStringValue("test")}, }, "null": { - input: SetNull(StringType), + input: NewSetNull(StringType{}), expected: nil, }, "unknown": { - input: SetUnknown(StringType), + input: NewSetUnknown(StringType{}), expected: nil, }, } @@ -889,24 +889,24 @@ func TestSetElements(t *testing.T) { } } -func TestSetElementType(t *testing.T) { +func TestSetValueElementType(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Set + input SetValue expected attr.Type }{ "known": { - input: SetValueMust(StringType, []attr.Value{StringValue("test")}), - expected: StringType, + input: NewSetValueMust(StringType{}, []attr.Value{NewStringValue("test")}), + expected: StringType{}, }, "null": { - input: SetNull(StringType), - expected: StringType, + input: NewSetNull(StringType{}), + expected: StringType{}, }, "unknown": { - input: SetUnknown(StringType), - expected: StringType, + input: NewSetUnknown(StringType{}), + expected: StringType{}, }, } @@ -925,163 +925,163 @@ func TestSetElementType(t *testing.T) { } } -func TestSetEqual(t *testing.T) { +func TestSetValueEqual(t *testing.T) { t.Parallel() type testCase struct { - receiver Set + receiver SetValue input attr.Value expected bool } tests := map[string]testCase{ "known-known": { - receiver: SetValueMust( - StringType, + receiver: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expected: true, }, "known-known-diff-value": { - receiver: SetValueMust( - StringType, + receiver: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("goodnight"), - StringValue("moon"), + NewStringValue("goodnight"), + NewStringValue("moon"), }, ), expected: false, }, "known-known-diff-length": { - receiver: SetValueMust( - StringType, + receiver: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), - StringValue("extra"), + NewStringValue("hello"), + NewStringValue("world"), + NewStringValue("extra"), }, ), expected: false, }, "known-known-diff-type": { - receiver: SetValueMust( - StringType, + receiver: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: SetValueMust( - BoolType, + input: NewSetValueMust( + BoolType{}, []attr.Value{ - BoolValue(false), - BoolValue(true), + NewBoolValue(false), + NewBoolValue(true), }, ), expected: false, }, "known-known-diff-unknown": { - receiver: SetValueMust( - StringType, + receiver: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringUnknown(), + NewStringValue("hello"), + NewStringUnknown(), }, ), - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expected: false, }, "known-known-diff-null": { - receiver: SetValueMust( - StringType, + receiver: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringNull(), + NewStringValue("hello"), + NewStringNull(), }, ), - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expected: false, }, "known-unknown": { - receiver: SetValueMust( - StringType, + receiver: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: SetUnknown(StringType), + input: NewSetUnknown(StringType{}), expected: false, }, "known-null": { - receiver: SetValueMust( - StringType, + receiver: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: SetNull(StringType), + input: NewSetNull(StringType{}), expected: false, }, "known-diff-type": { - receiver: SetValueMust( - StringType, + receiver: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - input: ListValueMust( - StringType, + input: NewListValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expected: false, }, "known-nil": { - receiver: SetValueMust( - StringType, + receiver: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), input: nil, @@ -1101,23 +1101,23 @@ func TestSetEqual(t *testing.T) { } } -func TestSetIsNull(t *testing.T) { +func TestSetValueIsNull(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Set + input SetValue expected bool }{ "known": { - input: SetValueMust(StringType, []attr.Value{StringValue("test")}), + input: NewSetValueMust(StringType{}, []attr.Value{NewStringValue("test")}), expected: false, }, "null": { - input: SetNull(StringType), + input: NewSetNull(StringType{}), expected: true, }, "unknown": { - input: SetUnknown(StringType), + input: NewSetUnknown(StringType{}), expected: false, }, } @@ -1137,23 +1137,23 @@ func TestSetIsNull(t *testing.T) { } } -func TestSetIsUnknown(t *testing.T) { +func TestSetValueIsUnknown(t *testing.T) { t.Parallel() testCases := map[string]struct { - input Set + input SetValue expected bool }{ "known": { - input: SetValueMust(StringType, []attr.Value{StringValue("test")}), + input: NewSetValueMust(StringType{}, []attr.Value{NewStringValue("test")}), expected: false, }, "null": { - input: SetNull(StringType), + input: NewSetNull(StringType{}), expected: false, }, "unknown": { - input: SetUnknown(StringType), + input: NewSetUnknown(StringType{}), expected: true, }, } @@ -1173,42 +1173,42 @@ func TestSetIsUnknown(t *testing.T) { } } -func TestSetString(t *testing.T) { +func TestSetValueString(t *testing.T) { t.Parallel() type testCase struct { - input Set + input SetValue expectation string } tests := map[string]testCase{ "known": { - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), expectation: `["hello","world"]`, }, "known-set-of-sets": { - input: SetValueMust( + input: NewSetValueMust( SetType{ - ElemType: StringType, + ElemType: StringType{}, }, []attr.Value{ - SetValueMust( - StringType, + NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - SetValueMust( - StringType, + NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("foo"), - StringValue("bar"), + NewStringValue("foo"), + NewStringValue("bar"), }, ), }, @@ -1216,15 +1216,15 @@ func TestSetString(t *testing.T) { expectation: `[["hello","world"],["foo","bar"]]`, }, "unknown": { - input: SetUnknown(StringType), + input: NewSetUnknown(StringType{}), expectation: "", }, "null": { - input: SetNull(StringType), + input: NewSetNull(StringType{}), expectation: "", }, "zero-value": { - input: Set{}, + input: SetValue{}, expectation: "", }, } @@ -1242,59 +1242,59 @@ func TestSetString(t *testing.T) { } } -func TestSetType(t *testing.T) { +func TestSetValueType(t *testing.T) { t.Parallel() type testCase struct { - input Set + input SetValue expectation attr.Type } tests := map[string]testCase{ "known": { - input: SetValueMust( - StringType, + input: NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - expectation: SetType{ElemType: StringType}, + expectation: SetType{ElemType: StringType{}}, }, "known-set-of-sets": { - input: SetValueMust( + input: NewSetValueMust( SetType{ - ElemType: StringType, + ElemType: StringType{}, }, []attr.Value{ - SetValueMust( - StringType, + NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("hello"), - StringValue("world"), + NewStringValue("hello"), + NewStringValue("world"), }, ), - SetValueMust( - StringType, + NewSetValueMust( + StringType{}, []attr.Value{ - StringValue("foo"), - StringValue("bar"), + NewStringValue("foo"), + NewStringValue("bar"), }, ), }, ), expectation: SetType{ ElemType: SetType{ - ElemType: StringType, + ElemType: StringType{}, }, }, }, "unknown": { - input: SetUnknown(StringType), - expectation: SetType{ElemType: StringType}, + input: NewSetUnknown(StringType{}), + expectation: SetType{ElemType: StringType{}}, }, "null": { - input: SetNull(StringType), - expectation: SetType{ElemType: StringType}, + input: NewSetNull(StringType{}), + expectation: SetType{ElemType: StringType{}}, }, } diff --git a/types/string.go b/types/basetypes/string.go similarity index 69% rename from types/string.go rename to types/basetypes/string.go index e99679a92..a9c7b8cb5 100644 --- a/types/string.go +++ b/types/basetypes/string.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -11,7 +11,7 @@ import ( ) var ( - _ StringValuable = String{} + _ StringValuable = StringValue{} ) // StringValuable extends attr.Value for string value types. @@ -20,60 +20,45 @@ type StringValuable interface { attr.Value // ToStringValue should convert the value type to a String. - ToStringValue(ctx context.Context) (String, diag.Diagnostics) + ToStringValue(ctx context.Context) (StringValue, diag.Diagnostics) } -// StringNull creates a String with a null value. Determine whether the value is +// NewStringNull creates a String with a null value. Determine whether the value is // null via the String type IsNull method. // // Setting the deprecated String type Null, Unknown, or Value fields after // creating a String with this function has no effect. -func StringNull() String { - return String{ +func NewStringNull() StringValue { + return StringValue{ state: attr.ValueStateNull, } } -// StringUnknown creates a String with an unknown value. Determine whether the +// NewStringUnknown creates a String with an unknown value. Determine whether the // value is unknown via the String type IsUnknown method. // // Setting the deprecated String type Null, Unknown, or Value fields after // creating a String with this function has no effect. -func StringUnknown() String { - return String{ +func NewStringUnknown() StringValue { + return StringValue{ state: attr.ValueStateUnknown, } } -// StringValue creates a String with a known value. Access the value via the String +// NewStringValue creates a String with a known value. Access the value via the String // type ValueString method. // // Setting the deprecated String type Null, Unknown, or Value fields after // creating a String with this function has no effect. -func StringValue(value string) String { - return String{ +func NewStringValue(value string) StringValue { + return StringValue{ state: attr.ValueStateKnown, value: value, } } -func stringValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { - if !in.IsKnown() { - return StringUnknown(), nil - } - if in.IsNull() { - return StringNull(), nil - } - var s string - err := in.As(&s) - if err != nil { - return nil, err - } - return StringValue(s), nil -} - -// String represents a UTF-8 string value. -type String struct { +// StringValue represents a UTF-8 string value. +type StringValue struct { // state represents whether the value is null, unknown, or known. The // zero-value is null. state attr.ValueState @@ -83,12 +68,12 @@ type String struct { } // Type returns a StringType. -func (s String) Type(_ context.Context) attr.Type { - return StringType +func (s StringValue) Type(_ context.Context) attr.Type { + return StringType{} } // ToTerraformValue returns the data contained in the *String as a tftypes.Value. -func (s String) ToTerraformValue(_ context.Context) (tftypes.Value, error) { +func (s StringValue) ToTerraformValue(_ context.Context) (tftypes.Value, error) { switch s.state { case attr.ValueStateKnown: if err := tftypes.ValidateValue(tftypes.String, s.value); err != nil { @@ -106,8 +91,8 @@ func (s String) ToTerraformValue(_ context.Context) (tftypes.Value, error) { } // Equal returns true if `other` is a String and has the same value as `s`. -func (s String) Equal(other attr.Value) bool { - o, ok := other.(String) +func (s StringValue) Equal(other attr.Value) bool { + o, ok := other.(StringValue) if !ok { return false @@ -125,12 +110,12 @@ func (s String) Equal(other attr.Value) bool { } // IsNull returns true if the String represents a null value. -func (s String) IsNull() bool { +func (s StringValue) IsNull() bool { return s.state == attr.ValueStateNull } // IsUnknown returns true if the String represents a currently unknown value. -func (s String) IsUnknown() bool { +func (s StringValue) IsUnknown() bool { return s.state == attr.ValueStateUnknown } @@ -139,7 +124,7 @@ func (s String) IsUnknown() bool { // // The string returned here is not protected by any compatibility guarantees, // and is intended for logging and error reporting. -func (s String) String() string { +func (s StringValue) String() string { if s.IsUnknown() { return attr.UnknownValueString } @@ -153,11 +138,11 @@ func (s String) String() string { // ValueString returns the known string value. If String is null or unknown, returns // "". -func (s String) ValueString() string { +func (s StringValue) ValueString() string { return s.value } // ToStringValue returns String. -func (s String) ToStringValue(context.Context) (String, diag.Diagnostics) { +func (s StringValue) ToStringValue(context.Context) (StringValue, diag.Diagnostics) { return s, nil } diff --git a/types/string_test.go b/types/basetypes/string_test.go similarity index 73% rename from types/string_test.go rename to types/basetypes/string_test.go index f87e76416..896cf022c 100644 --- a/types/string_test.go +++ b/types/basetypes/string_test.go @@ -1,4 +1,4 @@ -package types +package basetypes import ( "context" @@ -9,13 +9,9 @@ import ( "github.com/hashicorp/terraform-plugin-go/tftypes" ) -func TestStringValueFromTerraform(t *testing.T) { +func TestStringTypeValueFromTerraform(t *testing.T) { t.Parallel() - testStringValueFromTerraform(t, true) -} - -func testStringValueFromTerraform(t *testing.T, direct bool) { type testCase struct { input tftypes.Value expectation attr.Value @@ -24,15 +20,15 @@ func testStringValueFromTerraform(t *testing.T, direct bool) { tests := map[string]testCase{ "true": { input: tftypes.NewValue(tftypes.String, "hello"), - expectation: StringValue("hello"), + expectation: NewStringValue("hello"), }, "unknown": { input: tftypes.NewValue(tftypes.String, tftypes.UnknownValue), - expectation: StringUnknown(), + expectation: NewStringUnknown(), }, "null": { input: tftypes.NewValue(tftypes.String, nil), - expectation: StringNull(), + expectation: NewStringNull(), }, "wrongType": { input: tftypes.NewValue(tftypes.Number, 123), @@ -45,11 +41,7 @@ func testStringValueFromTerraform(t *testing.T, direct bool) { t.Parallel() ctx := context.Background() - f := StringType.ValueFromTerraform - if direct { - f = stringValueFromTerraform - } - got, err := f(ctx, test.input) + got, err := StringType{}.ValueFromTerraform(ctx, test.input) if err != nil { if test.expectedErr == "" { t.Errorf("Unexpected error: %s", err) @@ -80,24 +72,24 @@ func testStringValueFromTerraform(t *testing.T, direct bool) { } } -func TestStringToTerraformValue(t *testing.T) { +func TestStringValueToTerraformValue(t *testing.T) { t.Parallel() type testCase struct { - input String + input StringValue expectation interface{} } tests := map[string]testCase{ "known": { - input: StringValue("test"), + input: NewStringValue("test"), expectation: tftypes.NewValue(tftypes.String, "test"), }, "unknown": { - input: StringUnknown(), + input: NewStringUnknown(), expectation: tftypes.NewValue(tftypes.String, tftypes.UnknownValue), }, "null": { - input: StringNull(), + input: NewStringNull(), expectation: tftypes.NewValue(tftypes.String, nil), }, } @@ -119,63 +111,63 @@ func TestStringToTerraformValue(t *testing.T) { } } -func TestStringEqual(t *testing.T) { +func TestStringValueEqual(t *testing.T) { t.Parallel() type testCase struct { - input String + input StringValue candidate attr.Value expectation bool } tests := map[string]testCase{ "known-known-same": { - input: StringValue("test"), - candidate: StringValue("test"), + input: NewStringValue("test"), + candidate: NewStringValue("test"), expectation: true, }, "known-known-diff": { - input: StringValue("test"), - candidate: StringValue("not-test"), + input: NewStringValue("test"), + candidate: NewStringValue("not-test"), expectation: false, }, "known-unknown": { - input: StringValue("test"), - candidate: StringUnknown(), + input: NewStringValue("test"), + candidate: NewStringUnknown(), expectation: false, }, "known-null": { - input: StringValue("test"), - candidate: StringNull(), + input: NewStringValue("test"), + candidate: NewStringNull(), expectation: false, }, "unknown-value": { - input: StringUnknown(), - candidate: StringValue("test"), + input: NewStringUnknown(), + candidate: NewStringValue("test"), expectation: false, }, "unknown-unknown": { - input: StringUnknown(), - candidate: StringUnknown(), + input: NewStringUnknown(), + candidate: NewStringUnknown(), expectation: true, }, "unknown-null": { - input: StringUnknown(), - candidate: StringNull(), + input: NewStringUnknown(), + candidate: NewStringNull(), expectation: false, }, "null-known": { - input: StringNull(), - candidate: StringValue("test"), + input: NewStringNull(), + candidate: NewStringValue("test"), expectation: false, }, "null-unknown": { - input: StringNull(), - candidate: StringUnknown(), + input: NewStringNull(), + candidate: NewStringUnknown(), expectation: false, }, "null-null": { - input: StringNull(), - candidate: StringNull(), + input: NewStringNull(), + candidate: NewStringNull(), expectation: true, }, } @@ -192,23 +184,23 @@ func TestStringEqual(t *testing.T) { } } -func TestStringIsNull(t *testing.T) { +func TestStringValueIsNull(t *testing.T) { t.Parallel() testCases := map[string]struct { - input String + input StringValue expected bool }{ "known": { - input: StringValue("test"), + input: NewStringValue("test"), expected: false, }, "null": { - input: StringNull(), + input: NewStringNull(), expected: true, }, "unknown": { - input: StringUnknown(), + input: NewStringUnknown(), expected: false, }, } @@ -228,23 +220,23 @@ func TestStringIsNull(t *testing.T) { } } -func TestStringIsUnknown(t *testing.T) { +func TestStringValueIsUnknown(t *testing.T) { t.Parallel() testCases := map[string]struct { - input String + input StringValue expected bool }{ "known": { - input: StringValue("test"), + input: NewStringValue("test"), expected: false, }, "null": { - input: StringNull(), + input: NewStringNull(), expected: false, }, "unknown": { - input: StringUnknown(), + input: NewStringUnknown(), expected: true, }, } @@ -264,36 +256,36 @@ func TestStringIsUnknown(t *testing.T) { } } -func TestStringString(t *testing.T) { +func TestStringValueString(t *testing.T) { t.Parallel() type testCase struct { - input String + input StringValue expectation string } tests := map[string]testCase{ "known-non-empty": { - input: StringValue("test"), + input: NewStringValue("test"), expectation: `"test"`, }, "known-empty": { - input: StringValue(""), + input: NewStringValue(""), expectation: `""`, }, "known-quotes": { - input: StringValue(`testing is "fun"`), + input: NewStringValue(`testing is "fun"`), expectation: `"testing is \"fun\""`, }, "unknown": { - input: StringUnknown(), + input: NewStringUnknown(), expectation: "", }, "null": { - input: StringNull(), + input: NewStringNull(), expectation: "", }, "zero-value": { - input: String{}, + input: StringValue{}, expectation: ``, }, } @@ -311,23 +303,23 @@ func TestStringString(t *testing.T) { } } -func TestStringValueString(t *testing.T) { +func TestStringValueValueString(t *testing.T) { t.Parallel() testCases := map[string]struct { - input String + input StringValue expected string }{ "known": { - input: StringValue("test"), + input: NewStringValue("test"), expected: "test", }, "null": { - input: StringNull(), + input: NewStringNull(), expected: "", }, "unknown": { - input: StringUnknown(), + input: NewStringUnknown(), expected: "", }, } diff --git a/types/basetypes/string_type.go b/types/basetypes/string_type.go new file mode 100644 index 000000000..95c0920c8 --- /dev/null +++ b/types/basetypes/string_type.go @@ -0,0 +1,83 @@ +package basetypes + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// StringTypable extends attr.Type for string types. +// Implement this interface to create a custom StringType type. +type StringTypable interface { + attr.Type + + // ValueFromString should convert the String to a StringValuable type. + ValueFromString(context.Context, StringValue) (StringValuable, diag.Diagnostics) +} + +var _ StringTypable = StringType{} + +// StringType is the base framework type for a string. StringValue is the +// associated value type. +type StringType struct{} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// type. +func (t StringType) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, t.String()) +} + +// Equal returns true if the given type is equivalent. +func (t StringType) Equal(o attr.Type) bool { + _, ok := o.(StringType) + + return ok +} + +// String returns a human readable string of the type name. +func (t StringType) String() string { + return "basetypes.StringType" +} + +// TerraformType returns the tftypes.Type that should be used to represent this +// framework type. +func (t StringType) TerraformType(_ context.Context) tftypes.Type { + return tftypes.String +} + +// ValueFromString returns a StringValuable type given a StringValue. +func (t StringType) ValueFromString(_ context.Context, v StringValue) (StringValuable, diag.Diagnostics) { + return v, nil +} + +// ValueFromTerraform returns a Value given a tftypes.Value. This is meant to +// convert the tftypes.Value into a more convenient Go type for the provider to +// consume the data with. +func (t StringType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if !in.IsKnown() { + return NewStringUnknown(), nil + } + + if in.IsNull() { + return NewStringNull(), nil + } + + var s string + + err := in.As(&s) + + if err != nil { + return nil, err + } + + return NewStringValue(s), nil +} + +// ValueType returns the Value type. +func (t StringType) ValueType(_ context.Context) attr.Value { + // This Value does not need to be valid. + return StringValue{} +} diff --git a/types/bool_type.go b/types/bool_type.go new file mode 100644 index 000000000..03b67c74a --- /dev/null +++ b/types/bool_type.go @@ -0,0 +1,5 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +var BoolType = basetypes.BoolType{} diff --git a/types/bool_value.go b/types/bool_value.go new file mode 100644 index 000000000..fd6591a66 --- /dev/null +++ b/types/bool_value.go @@ -0,0 +1,23 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type Bool = basetypes.BoolValue + +// BoolNull creates a Bool with a null value. Determine whether the value is +// null via the Bool type IsNull method. +func BoolNull() basetypes.BoolValue { + return basetypes.NewBoolNull() +} + +// BoolUnknown creates a Bool with an unknown value. Determine whether the +// value is unknown via the Bool type IsUnknown method. +func BoolUnknown() basetypes.BoolValue { + return basetypes.NewBoolUnknown() +} + +// BoolValue creates a Bool with a known value. Access the value via the Bool +// type ValueBool method. +func BoolValue(value bool) basetypes.BoolValue { + return basetypes.NewBoolValue(value) +} diff --git a/types/doc.go b/types/doc.go index 4d4e9f00f..d72ca0a17 100644 --- a/types/doc.go +++ b/types/doc.go @@ -1,4 +1,8 @@ // Package types contains the framework-defined data types and values, such as -// boolean, floating point, integer, list, map, object, set, and string. These -// types can be extended by providers for custom use cases. +// boolean, floating point, integer, list, map, object, set, and string. +// +// This package contains creation functions and type aliases for most provider +// use cases. The actual schema-ready type and value type implementations are +// under the basetypes package. Embed those basetypes implementations to create +// custom types. package types diff --git a/types/float64_type.go b/types/float64_type.go new file mode 100644 index 000000000..717d99848 --- /dev/null +++ b/types/float64_type.go @@ -0,0 +1,5 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +var Float64Type = basetypes.Float64Type{} diff --git a/types/float64_value.go b/types/float64_value.go new file mode 100644 index 000000000..cd6bb6c67 --- /dev/null +++ b/types/float64_value.go @@ -0,0 +1,23 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type Float64 = basetypes.Float64Value + +// Float64Null creates a Float64 with a null value. Determine whether the value is +// null via the Float64 type IsNull method. +func Float64Null() basetypes.Float64Value { + return basetypes.NewFloat64Null() +} + +// Float64Unknown creates a Float64 with an unknown value. Determine whether the +// value is unknown via the Float64 type IsUnknown method. +func Float64Unknown() basetypes.Float64Value { + return basetypes.NewFloat64Unknown() +} + +// Float64Value creates a Float64 with a known value. Access the value via the Float64 +// type ValueFloat64 method. +func Float64Value(value float64) basetypes.Float64Value { + return basetypes.NewFloat64Value(value) +} diff --git a/types/int64.go b/types/int64.go deleted file mode 100644 index bae5a6e87..000000000 --- a/types/int64.go +++ /dev/null @@ -1,234 +0,0 @@ -package types - -import ( - "context" - "fmt" - "math/big" - - "github.com/hashicorp/terraform-plugin-go/tftypes" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" -) - -var ( - _ Int64Valuable = Int64{} -) - -// Int64Valuable extends attr.Value for int64 value types. -// Implement this interface to create a custom Int64 value type. -type Int64Valuable interface { - attr.Value - - // ToInt64Value should convert the value type to an Int64. - ToInt64Value(ctx context.Context) (Int64, diag.Diagnostics) -} - -// Int64Null creates a Int64 with a null value. Determine whether the value is -// null via the Int64 type IsNull method. -// -// Setting the deprecated Int64 type Null, Unknown, or Value fields after -// creating a Int64 with this function has no effect. -func Int64Null() Int64 { - return Int64{ - state: attr.ValueStateNull, - } -} - -// Int64Unknown creates a Int64 with an unknown value. Determine whether the -// value is unknown via the Int64 type IsUnknown method. -// -// Setting the deprecated Int64 type Null, Unknown, or Value fields after -// creating a Int64 with this function has no effect. -func Int64Unknown() Int64 { - return Int64{ - state: attr.ValueStateUnknown, - } -} - -// Int64Value creates a Int64 with a known value. Access the value via the Int64 -// type ValueInt64 method. -// -// Setting the deprecated Int64 type Null, Unknown, or Value fields after -// creating a Int64 with this function has no effect. -func Int64Value(value int64) Int64 { - return Int64{ - state: attr.ValueStateKnown, - value: value, - } -} - -func int64Validate(_ context.Context, in tftypes.Value, path path.Path) diag.Diagnostics { - var diags diag.Diagnostics - - if in.Type() == nil { - return diags - } - - if !in.Type().Equal(tftypes.Number) { - diags.AddAttributeError( - path, - "Int64 Type Validation Error", - "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ - fmt.Sprintf("Expected Number value, received %T with value: %v", in, in), - ) - return diags - } - - if !in.IsKnown() || in.IsNull() { - return diags - } - - var value *big.Float - err := in.As(&value) - - if err != nil { - diags.AddAttributeError( - path, - "Int64 Type Validation Error", - "An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+ - fmt.Sprintf("Cannot convert value to big.Float: %s", err), - ) - return diags - } - - if !value.IsInt() { - diags.AddAttributeError( - path, - "Int64 Type Validation Error", - fmt.Sprintf("Value %s is not an integer.", value), - ) - return diags - } - - _, accuracy := value.Int64() - - if accuracy != 0 { - diags.AddAttributeError( - path, - "Int64 Type Validation Error", - fmt.Sprintf("Value %s cannot be represented as a 64-bit integer.", value), - ) - return diags - } - - return diags -} - -func int64ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { - if !in.IsKnown() { - return Int64Unknown(), nil - } - - if in.IsNull() { - return Int64Null(), nil - } - - var bigF *big.Float - err := in.As(&bigF) - - if err != nil { - return nil, err - } - - if !bigF.IsInt() { - return nil, fmt.Errorf("Value %s is not an integer.", bigF) - } - - i, accuracy := bigF.Int64() - - if accuracy != 0 { - return nil, fmt.Errorf("Value %s cannot be represented as a 64-bit integer.", bigF) - } - - return Int64Value(i), nil -} - -// Int64 represents a 64-bit integer value, exposed as an int64. -type Int64 struct { - // state represents whether the value is null, unknown, or known. The - // zero-value is null. - state attr.ValueState - - // value contains the known value, if not null or unknown. - value int64 -} - -// Equal returns true if `other` is an Int64 and has the same value as `i`. -func (i Int64) Equal(other attr.Value) bool { - o, ok := other.(Int64) - - if !ok { - return false - } - - if i.state != o.state { - return false - } - - if i.state != attr.ValueStateKnown { - return true - } - - return i.value == o.value -} - -// ToTerraformValue returns the data contained in the Int64 as a tftypes.Value. -func (i Int64) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { - switch i.state { - case attr.ValueStateKnown: - if err := tftypes.ValidateValue(tftypes.Number, i.value); err != nil { - return tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), err - } - - return tftypes.NewValue(tftypes.Number, i.value), nil - case attr.ValueStateNull: - return tftypes.NewValue(tftypes.Number, nil), nil - case attr.ValueStateUnknown: - return tftypes.NewValue(tftypes.Number, tftypes.UnknownValue), nil - default: - panic(fmt.Sprintf("unhandled Int64 state in ToTerraformValue: %s", i.state)) - } -} - -// Type returns a Int64Type. -func (i Int64) Type(ctx context.Context) attr.Type { - return Int64Type -} - -// IsNull returns true if the Int64 represents a null value. -func (i Int64) IsNull() bool { - return i.state == attr.ValueStateNull -} - -// IsUnknown returns true if the Int64 represents a currently unknown value. -func (i Int64) IsUnknown() bool { - return i.state == attr.ValueStateUnknown -} - -// String returns a human-readable representation of the Int64 value. -// The string returned here is not protected by any compatibility guarantees, -// and is intended for logging and error reporting. -func (i Int64) String() string { - if i.IsUnknown() { - return attr.UnknownValueString - } - - if i.IsNull() { - return attr.NullValueString - } - - return fmt.Sprintf("%d", i.value) -} - -// ValueInt64 returns the known float64 value. If Int64 is null or unknown, returns -// 0.0. -func (i Int64) ValueInt64() int64 { - return i.value -} - -// ToInt64Value returns Int64. -func (i Int64) ToInt64Value(context.Context) (Int64, diag.Diagnostics) { - return i, nil -} diff --git a/types/int64_type.go b/types/int64_type.go new file mode 100644 index 000000000..52f20876d --- /dev/null +++ b/types/int64_type.go @@ -0,0 +1,5 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +var Int64Type = basetypes.Int64Type{} diff --git a/types/int64_value.go b/types/int64_value.go new file mode 100644 index 000000000..fdb146f52 --- /dev/null +++ b/types/int64_value.go @@ -0,0 +1,23 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type Int64 = basetypes.Int64Value + +// Int64Null creates a Int64 with a null value. Determine whether the value is +// null via the Int64 type IsNull method. +func Int64Null() basetypes.Int64Value { + return basetypes.NewInt64Null() +} + +// Int64Unknown creates a Int64 with an unknown value. Determine whether the +// value is unknown via the Int64 type IsUnknown method. +func Int64Unknown() basetypes.Int64Value { + return basetypes.NewInt64Unknown() +} + +// Int64Value creates a Int64 with a known value. Access the value via the +// Int64 type ValueInt64 method. +func Int64Value(value int64) basetypes.Int64Value { + return basetypes.NewInt64Value(value) +} diff --git a/types/list_type.go b/types/list_type.go new file mode 100644 index 000000000..8cd6d3df7 --- /dev/null +++ b/types/list_type.go @@ -0,0 +1,5 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type ListType = basetypes.ListType diff --git a/types/list_value.go b/types/list_value.go new file mode 100644 index 000000000..012963e26 --- /dev/null +++ b/types/list_value.go @@ -0,0 +1,47 @@ +package types + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type List = basetypes.ListValue + +// ListNull creates a List with a null value. Determine whether the value is +// null via the List type IsNull method. +func ListNull(elementType attr.Type) basetypes.ListValue { + return basetypes.NewListNull(elementType) +} + +// ListUnknown creates a List with an unknown value. Determine whether the +// value is unknown via the List type IsUnknown method. +func ListUnknown(elementType attr.Type) basetypes.ListValue { + return basetypes.NewListUnknown(elementType) +} + +// ListValue creates a List with a known value. Access the value via the List +// type Elements or ElementsAs methods. +func ListValue(elementType attr.Type, elements []attr.Value) (basetypes.ListValue, diag.Diagnostics) { + return basetypes.NewListValue(elementType, elements) +} + +// ListValueFrom creates a List with a known value, using reflection rules. +// The elements must be a slice which can convert into the given element type. +// Access the value via the List type Elements or ElementsAs methods. +func ListValueFrom(ctx context.Context, elementType attr.Type, elements any) (basetypes.ListValue, diag.Diagnostics) { + return basetypes.NewListValueFrom(ctx, elementType, elements) +} + +// ListValueMust creates a List with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the List +// type Elements or ElementsAs methods. +// +// This creation function is only recommended to create List values which will +// not potentially affect practitioners, such as testing, or exhaustively +// tested provider logic. +func ListValueMust(elementType attr.Type, elements []attr.Value) basetypes.ListValue { + return basetypes.NewListValueMust(elementType, elements) +} diff --git a/types/map_type.go b/types/map_type.go new file mode 100644 index 000000000..20bcdc587 --- /dev/null +++ b/types/map_type.go @@ -0,0 +1,5 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type MapType = basetypes.MapType diff --git a/types/map_value.go b/types/map_value.go new file mode 100644 index 000000000..444d79a5f --- /dev/null +++ b/types/map_value.go @@ -0,0 +1,47 @@ +package types + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type Map = basetypes.MapValue + +// MapNull creates a Map with a null value. Determine whether the value is +// null via the Map type IsNull method. +func MapNull(elementType attr.Type) basetypes.MapValue { + return basetypes.NewMapNull(elementType) +} + +// MapUnknown creates a Map with an unknown value. Determine whether the +// value is unknown via the Map type IsUnknown method. +func MapUnknown(elementType attr.Type) basetypes.MapValue { + return basetypes.NewMapUnknown(elementType) +} + +// MapValue creates a Map with a known value. Access the value via the Map +// type Elements or ElementsAs methods. +func MapValue(elementType attr.Type, elements map[string]attr.Value) (basetypes.MapValue, diag.Diagnostics) { + return basetypes.NewMapValue(elementType, elements) +} + +// MapValueFrom creates a Map with a known value, using reflection rules. +// The elements must be a map which can convert into the given element type. +// Access the value via the Map type Elements or ElementsAs methods. +func MapValueFrom(ctx context.Context, elementType attr.Type, elements any) (basetypes.MapValue, diag.Diagnostics) { + return basetypes.NewMapValueFrom(ctx, elementType, elements) +} + +// MapValueMust creates a Map with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the Map +// type Elements or ElementsAs methods. +// +// This creation function is only recommended to create Map values which will +// not potentially affect practitioners, such as testing, or exhaustively +// tested provider logic. +func MapValueMust(elementType attr.Type, elements map[string]attr.Value) basetypes.MapValue { + return basetypes.NewMapValueMust(elementType, elements) +} diff --git a/types/number_type.go b/types/number_type.go new file mode 100644 index 000000000..e74c1e1ac --- /dev/null +++ b/types/number_type.go @@ -0,0 +1,5 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +var NumberType = basetypes.NumberType{} diff --git a/types/number_value.go b/types/number_value.go new file mode 100644 index 000000000..86e26bbdf --- /dev/null +++ b/types/number_value.go @@ -0,0 +1,27 @@ +package types + +import ( + "math/big" + + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type Number = basetypes.NumberValue + +// NumberNull creates a Number with a null value. Determine whether the value is +// null via the Number type IsNull method. +func NumberNull() basetypes.NumberValue { + return basetypes.NewNumberNull() +} + +// NumberUnknown creates a Number with an unknown value. Determine whether the +// value is unknown via the Number type IsUnknown method. +func NumberUnknown() basetypes.NumberValue { + return basetypes.NewNumberUnknown() +} + +// NumberValue creates a Number with a known value. Access the value via the Number +// type ValueBigFloat method. If the given value is nil, a null Number is created. +func NumberValue(value *big.Float) basetypes.NumberValue { + return basetypes.NewNumberValue(value) +} diff --git a/types/object_type.go b/types/object_type.go new file mode 100644 index 000000000..688594f9a --- /dev/null +++ b/types/object_type.go @@ -0,0 +1,5 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type ObjectType = basetypes.ObjectType diff --git a/types/object_value.go b/types/object_value.go new file mode 100644 index 000000000..453bf3fa9 --- /dev/null +++ b/types/object_value.go @@ -0,0 +1,47 @@ +package types + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type Object = basetypes.ObjectValue + +// ObjectNull creates a Object with a null value. Determine whether the value is +// null via the Object type IsNull method. +func ObjectNull(attributeTypes map[string]attr.Type) basetypes.ObjectValue { + return basetypes.NewObjectNull(attributeTypes) +} + +// ObjectUnknown creates a Object with an unknown value. Determine whether the +// value is unknown via the Object type IsUnknown method. +func ObjectUnknown(attributeTypes map[string]attr.Type) basetypes.ObjectValue { + return basetypes.NewObjectUnknown(attributeTypes) +} + +// ObjectValue creates a Object with a known value. Access the value via the Object +// type Attributes or As methods. +func ObjectValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (basetypes.ObjectValue, diag.Diagnostics) { + return basetypes.NewObjectValue(attributeTypes, attributes) +} + +// ObjectValueFrom creates a Object with a known value, using reflection rules. +// The attributes must be a struct which can convert into the given attribute types. +// Access the value via the Object type Attributes or As methods. +func ObjectValueFrom(ctx context.Context, attributeTypes map[string]attr.Type, attributes any) (basetypes.ObjectValue, diag.Diagnostics) { + return basetypes.NewObjectValueFrom(ctx, attributeTypes, attributes) +} + +// ObjectValueMust creates a Object with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the Object +// type Attributes or As methods. +// +// This creation function is only recommended to create Object values which will +// not potentially affect practitioners, such as testing, or exhaustively +// tested provider logic. +func ObjectValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) basetypes.ObjectValue { + return basetypes.NewObjectValueMust(attributeTypes, attributes) +} diff --git a/types/primitive.go b/types/primitive.go deleted file mode 100644 index 7f917f396..000000000 --- a/types/primitive.go +++ /dev/null @@ -1,219 +0,0 @@ -package types - -import ( - "context" - "fmt" - - "github.com/hashicorp/terraform-plugin-go/tftypes" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-framework/attr/xattr" - "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" -) - -type primitive uint8 - -const ( - // StringType represents a UTF-8 string type. - StringType primitive = iota - - // NumberType represents a number type, either an integer or a float. - NumberType - - // BoolType represents a boolean type. - BoolType - - // Int64Type represents a 64-bit integer. - Int64Type - - // Float64Type represents a 64-bit floating point. - Float64Type -) - -var ( - _ StringTypable = StringType - _ NumberTypable = NumberType - _ BoolTypable = BoolType - _ Int64Typable = Int64Type - _ Float64Typable = Float64Type -) - -// StringTypable extends attr.Type for string types. -// Implement this interface to create a custom StringType type. -type StringTypable interface { - attr.Type - - // ValueFromString should convert the String to a StringValuable type. - ValueFromString(context.Context, String) (StringValuable, diag.Diagnostics) -} - -// NumberTypable extends attr.Type for number types. -// Implement this interface to create a custom NumberType type. -type NumberTypable interface { - attr.Type - - // ValueFromNumber should convert the Number to a NumberValuable type. - ValueFromNumber(context.Context, Number) (NumberValuable, diag.Diagnostics) -} - -// BoolTypable extends attr.Type for bool types. -// Implement this interface to create a custom BoolType type. -type BoolTypable interface { - attr.Type - - // ValueFromBool should convert the Bool to a BoolValuable type. - ValueFromBool(context.Context, Bool) (BoolValuable, diag.Diagnostics) -} - -// Int64Typable extends attr.Type for int64 types. -// Implement this interface to create a custom Int64Type type. -type Int64Typable interface { - xattr.TypeWithValidate - - // ValueFromInt64 should convert the Int64 to a Int64Valuable type. - ValueFromInt64(context.Context, Int64) (Int64Valuable, diag.Diagnostics) -} - -// Float64Typable extends attr.Type for float64 types. -// Implement this interface to create a custom Float64Type type. -type Float64Typable interface { - xattr.TypeWithValidate - - // ValueFromFloat64 should convert the Float64 to a Float64Valuable type. - ValueFromFloat64(context.Context, Float64) (Float64Valuable, diag.Diagnostics) -} - -// ValueFromString returns a StringValuable type given a String. -func (p primitive) ValueFromString(_ context.Context, s String) (StringValuable, diag.Diagnostics) { - return s, nil -} - -// ValueFromNumber returns a NumberValuable type given a Number. -func (p primitive) ValueFromNumber(_ context.Context, n Number) (NumberValuable, diag.Diagnostics) { - return n, nil -} - -// ValueFromBool returns a BoolValuable type given a Bool. -func (p primitive) ValueFromBool(_ context.Context, b Bool) (BoolValuable, diag.Diagnostics) { - return b, nil -} - -// ValueFromInt64 returns an Int64Valuable type given an Int64. -func (p primitive) ValueFromInt64(_ context.Context, i Int64) (Int64Valuable, diag.Diagnostics) { - return i, nil -} - -// ValueFromFloat64 returns a Float64Valuable type given a Float64. -func (p primitive) ValueFromFloat64(_ context.Context, f Float64) (Float64Valuable, diag.Diagnostics) { - return f, nil -} - -func (p primitive) String() string { - switch p { - case StringType: - return "types.StringType" - case NumberType: - return "types.NumberType" - case BoolType: - return "types.BoolType" - case Int64Type: - return "types.Int64Type" - case Float64Type: - return "types.Float64Type" - default: - return fmt.Sprintf("unknown primitive %d", p) - } -} - -// TerraformType returns the tftypes.Type that should be used to represent this -// type. This constrains what user input will be accepted and what kind of data -// can be set in state. The framework will use this to translate the Type to -// something Terraform can understand. -func (p primitive) TerraformType(_ context.Context) tftypes.Type { - switch p { - case StringType: - return tftypes.String - case NumberType, Int64Type, Float64Type: - return tftypes.Number - case BoolType: - return tftypes.Bool - default: - panic(fmt.Sprintf("unknown primitive %d", p)) - } -} - -// ValueFromTerraform returns a Value given a tftypes.Value. This is meant to -// convert the tftypes.Value into a more convenient Go type for the provider to -// consume the data with. -func (p primitive) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { - switch p { - case StringType: - return stringValueFromTerraform(ctx, in) - case NumberType: - return numberValueFromTerraform(ctx, in) - case BoolType: - return boolValueFromTerraform(ctx, in) - case Int64Type: - return int64ValueFromTerraform(ctx, in) - case Float64Type: - return float64ValueFromTerraform(ctx, in) - default: - panic(fmt.Sprintf("unknown primitive %d", p)) - } -} - -// ValueType returns the Value type. -func (p primitive) ValueType(_ context.Context) attr.Value { - // These Value do not need to be valid. - switch p { - case BoolType: - return Bool{} - case Float64Type: - return Float64{} - case Int64Type: - return Int64{} - case NumberType: - return Number{} - case StringType: - return String{} - default: - panic(fmt.Sprintf("unknown primitive %d", p)) - } -} - -// Equal returns true if `o` is also a primitive, and is the same type of -// primitive as `p`. -func (p primitive) Equal(o attr.Type) bool { - other, ok := o.(primitive) - if !ok { - return false - } - switch p { - case StringType, NumberType, BoolType, Int64Type, Float64Type: - return p == other - default: - // unrecognized types are never equal to anything. - return false - } -} - -// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the -// type. -func (p primitive) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { - return nil, fmt.Errorf("cannot apply AttributePathStep %T to %s", step, p.String()) -} - -// Validate implements type validation. -func (p primitive) Validate(ctx context.Context, in tftypes.Value, path path.Path) diag.Diagnostics { - var diags diag.Diagnostics - - switch p { - case Int64Type: - diags.Append(int64Validate(ctx, in, path)...) - case Float64Type: - diags.Append(float64Validate(ctx, in, path)...) - } - - return diags -} diff --git a/types/primitive_test.go b/types/primitive_test.go deleted file mode 100644 index d31a5dec5..000000000 --- a/types/primitive_test.go +++ /dev/null @@ -1,259 +0,0 @@ -package types - -import ( - "context" - "testing" - - "github.com/hashicorp/terraform-plugin-framework/attr" - "github.com/hashicorp/terraform-plugin-go/tftypes" -) - -func TestPrimitiveTerraformType(t *testing.T) { - t.Parallel() - - tests := map[primitive]tftypes.Type{ - StringType: tftypes.String, - NumberType: tftypes.Number, - BoolType: tftypes.Bool, - Int64Type: tftypes.Number, - Float64Type: tftypes.Number, - } - for prim, expected := range tests { - prim, expected := prim, expected - t.Run(prim.String(), func(t *testing.T) { - t.Parallel() - - got := prim.TerraformType(context.Background()) - if !got.Equal(expected) { - t.Errorf("Expected %s, got %s", expected, got) - } - }) - } -} - -func TestPrimitiveValueFromTerraform(t *testing.T) { - t.Parallel() - - t.Run(StringType.String(), func(t *testing.T) { - t.Parallel() - - testStringValueFromTerraform(t, false) - }) - - t.Run(NumberType.String(), func(t *testing.T) { - t.Parallel() - - testNumberValueFromTerraform(t, false) - }) - - t.Run(BoolType.String(), func(t *testing.T) { - t.Parallel() - - testBoolValueFromTerraform(t, false) - }) - - t.Run(Int64Type.String(), func(t *testing.T) { - t.Parallel() - - testInt64ValueFromTerraform(t, false) - }) - - t.Run(Float64Type.String(), func(t *testing.T) { - t.Parallel() - - testFloat64ValueFromTerraform(t, false) - }) -} - -// testAttributeType is a dummy attribute type to compare against with Equal to -// make sure we can handle unexpected types being passed in. -type testAttributeType struct{} - -func (t testAttributeType) TerraformType(_ context.Context) tftypes.Type { - panic("not implemented") -} - -func (t testAttributeType) ValueFromTerraform(_ context.Context, _ tftypes.Value) (attr.Value, error) { - panic("not implemented") -} - -func (t testAttributeType) Equal(_ attr.Type) bool { - panic("not implemented") -} - -func (t testAttributeType) ApplyTerraform5AttributePathStep(_ tftypes.AttributePathStep) (interface{}, error) { - panic("not implemented") -} - -// String should return a human-friendly version of the Type. -func (t testAttributeType) String() string { - panic("not implemented") -} - -// ValueType returns the Value type. -func (t testAttributeType) ValueType(_ context.Context) attr.Value { - panic("not implemented") -} - -func TestPrimitiveEqual(t *testing.T) { - t.Parallel() - - type testCase struct { - prim primitive - candidate attr.Type - expected bool - } - tests := map[string]testCase{ - "string-string": { - prim: StringType, - candidate: StringType, - expected: true, - }, - "string-number": { - prim: StringType, - candidate: NumberType, - expected: false, - }, - "string-bool": { - prim: StringType, - candidate: BoolType, - expected: false, - }, - "string-int64": { - prim: StringType, - candidate: Int64Type, - expected: false, - }, - "string-float64": { - prim: StringType, - candidate: Float64Type, - expected: false, - }, - "string-unknown": { - prim: StringType, - candidate: primitive(100), - expected: false, - }, - "string-wrongType": { - prim: StringType, - candidate: testAttributeType{}, - expected: false, - }, - "number-string": { - prim: NumberType, - candidate: StringType, - expected: false, - }, - "number-number": { - prim: NumberType, - candidate: NumberType, - expected: true, - }, - "number-bool": { - prim: NumberType, - candidate: BoolType, - expected: false, - }, - "number-int64": { - prim: NumberType, - candidate: Int64Type, - expected: false, - }, - "number-float64": { - prim: NumberType, - candidate: Float64Type, - expected: false, - }, - "number-unknown": { - prim: NumberType, - candidate: primitive(100), - expected: false, - }, - "number-wrongType": { - prim: NumberType, - candidate: testAttributeType{}, - expected: false, - }, - "bool-string": { - prim: BoolType, - candidate: StringType, - expected: false, - }, - "bool-number": { - prim: BoolType, - candidate: NumberType, - expected: false, - }, - "bool-bool": { - prim: BoolType, - candidate: BoolType, - expected: true, - }, - "bool-int64": { - prim: BoolType, - candidate: Int64Type, - expected: false, - }, - "bool-float64": { - prim: BoolType, - candidate: Float64Type, - expected: false, - }, - "bool-unknown": { - prim: BoolType, - candidate: primitive(100), - expected: false, - }, - "bool-wrongType": { - prim: BoolType, - candidate: testAttributeType{}, - expected: false, - }, - "unknown-string": { - prim: 100, - candidate: StringType, - expected: false, - }, - "unknown-number": { - prim: 100, - candidate: NumberType, - expected: false, - }, - "unknown-bool": { - prim: 100, - candidate: BoolType, - expected: false, - }, - "unknown-int64": { - prim: 100, - candidate: Int64Type, - expected: false, - }, - "unknown-float64": { - prim: 100, - candidate: Float64Type, - expected: false, - }, - "unknown-unknown": { - prim: 100, - candidate: primitive(100), - expected: false, - }, - "unknown-wrongType": { - prim: 100, - candidate: testAttributeType{}, - expected: false, - }, - } - for name, test := range tests { - name, test := name, test - t.Run(name, func(t *testing.T) { - t.Parallel() - - got := test.prim.Equal(test.candidate) - if got != test.expected { - t.Errorf("Expected %v, got %v", test.expected, got) - } - }) - } -} diff --git a/types/set_type.go b/types/set_type.go new file mode 100644 index 000000000..990b14314 --- /dev/null +++ b/types/set_type.go @@ -0,0 +1,5 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type SetType = basetypes.SetType diff --git a/types/set_value.go b/types/set_value.go new file mode 100644 index 000000000..31d5a6250 --- /dev/null +++ b/types/set_value.go @@ -0,0 +1,47 @@ +package types + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +type Set = basetypes.SetValue + +// SetNull creates a Set with a null value. Determine whether the value is +// null via the Set type IsNull method. +func SetNull(elementType attr.Type) basetypes.SetValue { + return basetypes.NewSetNull(elementType) +} + +// SetUnknown creates a Set with an unknown value. Determine whether the +// value is unknown via the Set type IsUnknown method. +func SetUnknown(elementType attr.Type) basetypes.SetValue { + return basetypes.NewSetUnknown(elementType) +} + +// SetValue creates a Set with a known value. Access the value via the Set +// type Elements or ElementsAs methods. +func SetValue(elementType attr.Type, elements []attr.Value) (basetypes.SetValue, diag.Diagnostics) { + return basetypes.NewSetValue(elementType, elements) +} + +// SetValueFrom creates a Set with a known value, using reflection rules. +// The elements must be a slice which can convert into the given element type. +// Access the value via the Set type Elements or ElementsAs methods. +func SetValueFrom(ctx context.Context, elementType attr.Type, elements any) (basetypes.SetValue, diag.Diagnostics) { + return basetypes.NewSetValueFrom(ctx, elementType, elements) +} + +// SetValueMust creates a Set with a known value, converting any diagnostics +// into a panic at runtime. Access the value via the Set +// type Elements or ElementsAs methods. +// +// This creation function is only recommended to create Set values which will +// not potentially affect practitioners, such as testing, or exhaustively +// tested provider logic. +func SetValueMust(elementType attr.Type, elements []attr.Value) basetypes.SetValue { + return basetypes.NewSetValueMust(elementType, elements) +} diff --git a/types/string_type.go b/types/string_type.go new file mode 100644 index 000000000..1f5c25199 --- /dev/null +++ b/types/string_type.go @@ -0,0 +1,5 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +var StringType = basetypes.StringType{} diff --git a/types/string_value.go b/types/string_value.go new file mode 100644 index 000000000..b7934199e --- /dev/null +++ b/types/string_value.go @@ -0,0 +1,23 @@ +package types + +import "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + +type String = basetypes.StringValue + +// StringNull creates a String with a null value. Determine whether the value is +// null via the String type IsNull method. +func StringNull() basetypes.StringValue { + return basetypes.NewStringNull() +} + +// StringUnknown creates a String with an unknown value. Determine whether the +// value is unknown via the String type IsUnknown method. +func StringUnknown() basetypes.StringValue { + return basetypes.NewStringUnknown() +} + +// StringValue creates a String with a known value. Access the value via the String +// type ValueString method. +func StringValue(value string) basetypes.StringValue { + return basetypes.NewStringValue(value) +}