Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
internal/fwschema: Introduce NestedAttribute interface and cleanup At…
…tribute interface methods (#543) Reference: #132 As part of upcoming effort to split schema functionality into the `datasource`, `provider`, and `resource` packages, there are some internal implementation details which need to be sorted beforehand. Throughout the 0.x versions, schema functionality has been migrated from the `tfsdk` package into the `internal/fwschema` package, but there is some lingering technical debt of duplicate and confusing methods. This change creates a new `NestedAttribute` (singular) interface which extends the `Attribute` interface with the methods only required for an attribute that does in fact implement nested attributes. The `tfsdk.Attribute` type is updated to support both the `Attribute` and `NestedAttribute` interfaces as it accurately describes the overloaded abstraction. The `NestedAttributes` (plural) interface remains to describe how `tfsdk.Attribute` implements that concepts under its `Attributes` field. The `NestedAttributes` (plural) interface and its implementations will be removed when `tfsdk.Attribute` is removed. Another aspect of these changes is cleaning up the type describing methods, removing the separate `Attribute` type `FrameworkType()` method and `NestedAttributes` type `AttributeType()` method. The upcoming split schemas will implement explicit attribute types which only implement `NestedAttribute` (singular) as appropriate.
- Loading branch information
Showing
27 changed files
with
269 additions
and
279 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
```release-note:breaking-change | ||
tfsdk: The `Attribute` type `FrameworkType()` method has been removed. Use the `GetType()` method instead which returns the same information. | ||
``` | ||
|
||
```release-note:breaking-change | ||
tfsdk: The `Attribute` type `GetAttributes()` method now returns underlying attribute information rather than another interface. Use the `GetNestingMode()` method to determine the nesting mode. | ||
``` | ||
|
||
```release-note:breaking-change | ||
tfsdk: The `Attribute` type `GetType()` method now returns type information whether the attribute implements the `Type` field or `Attributes` field. Use the `GetAttributes()` and `GetNestingMode()` methods to determine if the `Attributes` field is explicitly being used. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package fwschema | ||
|
||
// NestedAttribute defines a schema attribute that contains nested attributes. | ||
type NestedAttribute interface { | ||
Attribute | ||
|
||
// GetAttributes should return the nested attributes of an attribute, if | ||
// applicable. This is named differently than Attribute to prevent a | ||
// conflict with the tfsdk.Attribute field name. | ||
GetAttributes() UnderlyingAttributes | ||
|
||
// GetNestingMode should return the nesting mode (list, map, set, or | ||
// single) of the nested attributes or left unset if this Attribute | ||
// does not represent nested attributes. | ||
GetNestingMode() NestingMode | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package fwschema | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/hashicorp/terraform-plugin-framework/attr" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
"github.com/hashicorp/terraform-plugin-go/tftypes" | ||
) | ||
|
||
// Ensure UnderlyingAttributes satisfies the expected interfaces. | ||
var _ tftypes.AttributePathStepper = UnderlyingAttributes{} | ||
|
||
// UnderlyingAttributes represents attributes under a nested attribute. | ||
type UnderlyingAttributes map[string]Attribute | ||
|
||
// ApplyTerraform5AttributePathStep performs an AttributeName step on the | ||
// underlying attributes or returns an error. | ||
func (u UnderlyingAttributes) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { | ||
name, ok := step.(tftypes.AttributeName) | ||
|
||
if !ok { | ||
return nil, fmt.Errorf("can't apply %T to Attributes", step) | ||
} | ||
|
||
attribute, ok := u[string(name)] | ||
|
||
if !ok { | ||
return nil, fmt.Errorf("no attribute %q on Attributes", name) | ||
} | ||
|
||
return attribute, nil | ||
} | ||
|
||
// Equal returns true if all underlying attributes are equal. | ||
func (u UnderlyingAttributes) Equal(o UnderlyingAttributes) bool { | ||
if len(u) != len(o) { | ||
return false | ||
} | ||
|
||
for name, uAttribute := range u { | ||
oAttribute, ok := o[name] | ||
|
||
if !ok { | ||
return false | ||
} | ||
|
||
if !uAttribute.Equal(oAttribute) { | ||
return false | ||
} | ||
} | ||
|
||
return true | ||
} | ||
|
||
// Type returns the framework type of the underlying attributes. | ||
func (u UnderlyingAttributes) Type() attr.Type { | ||
attrTypes := make(map[string]attr.Type, len(u)) | ||
|
||
for name, attr := range u { | ||
attrTypes[name] = attr.GetType() | ||
} | ||
|
||
return types.ObjectType{ | ||
AttrTypes: attrTypes, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.