Skip to content

Commit

Permalink
extract attribute package
Browse files Browse the repository at this point in the history
  • Loading branch information
kmoe committed May 10, 2021
1 parent b6b3471 commit a31fc38
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 72 deletions.
58 changes: 58 additions & 0 deletions attribute/attribute.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package attribute

import (
"context"

"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/hashicorp/terraform-plugin-go/tftypes"
)

// AttributeType defines an interface for describing a kind of attribute.
// AttributeTypes are collections of constraints and behaviors such that they
// can be reused on multiple attributes easily.
type AttributeType interface {
// 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 AttributeType to something Terraform
// can understand.
TerraformType(context.Context) tftypes.Type

// Validate returns any warnings or errors about the value that is
// being used to populate the AttributeType. It is generally used to
// check the data format and ensure that it complies with the
// requirements of the AttributeType.
//
// TODO: don't use tfprotov6.Diagnostic, use our type
Validate(context.Context, tftypes.Value) []*tfprotov6.Diagnostic

// Description returns a practitioner-friendly explanation of the type
// and the constraints of the data it accepts and returns. It will be
// combined with the Description associated with the Attribute.
Description(context.Context, StringKind) string

// ValueFromTerraform returns an AttributeValue 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.
ValueFromTerraform(context.Context, tftypes.Value) (AttributeValue, error)
}

// StringKind represents a kind of string formatting.
type StringKind uint8

// NestingMode represents a specific way a group of attributes can be nested.
type NestingMode uint8

// AttributeValue defines an interface for describing data associated with an
// attribute. AttributeValues allow provider developers to specify data in a
// convenient format, and have it transparently be converted to formats
// Terraform understands.
type AttributeValue interface {
// ToTerraformValue returns the data contained in the AttributeValue as
// a Go type that tftypes.NewValue will accept.
ToTerraformValue(context.Context) (interface{}, error)

// Equal must return true if the AttributeValue is considered
// semantically equal to the AttributeValue passed as an argument.
Equal(AttributeValue) bool
}
69 changes: 8 additions & 61 deletions schema.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package tf

import (
"context"

"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/hashicorp/terraform-plugin-go/tftypes"
"github.com/hashicorp/terraform-plugin-framework/attribute"
)

const (
NestingModeSingle NestingMode = 0
NestingModeList NestingMode = 1
NestingModeSet NestingMode = 2
NestingModeMap NestingMode = 3
NestingModeSingle attribute.NestingMode = 0
NestingModeList attribute.NestingMode = 1
NestingModeSet attribute.NestingMode = 2
NestingModeMap attribute.NestingMode = 3
)

// Schema is used to define the shape of practitioner-provider information,
Expand Down Expand Up @@ -39,7 +36,7 @@ type Attribute struct {
// want to use one of the types in the types package.
//
// If Type is set, Attributes cannot be.
Type AttributeType
Type attribute.AttributeType

// Attributes can have their own, nested attributes. This nested map of
// attributes behaves exactly like the map of attributes on the Schema
Expand All @@ -54,7 +51,7 @@ type Attribute struct {
// AttributesNestingMode controls the various ways these sub-groups of
// attributes can behave. It can only be used with Attributes, and must
// not be set if Type is set.
AttributesNestingMode NestingMode
AttributesNestingMode attribute.NestingMode

// Description is used in various tooling, like the documentation
// generator and the language server, to give practitioners more
Expand All @@ -66,7 +63,7 @@ type Attribute struct {
// Description uses. It should be Markdown or PlainText.
//
// TODO: come up with a better interface for this, this is weird.
DescriptionKind StringKind
DescriptionKind attribute.StringKind

// Required indicates whether the practitioner must enter a value for
// this attribute or not. Required and Optional cannot both be true,
Expand Down Expand Up @@ -97,53 +94,3 @@ type Attribute struct {
// instructing them on what upgrade steps to take.
DeprecationMessage string
}

// AttributeType defines an interface for describing a kind of attribute.
// AttributeTypes are collections of constraints and behaviors such that they
// can be reused on multiple attributes easily.
type AttributeType interface {
// 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 AttributeType to something Terraform
// can understand.
TerraformType(context.Context) tftypes.Type

// Validate returns any warnings or errors about the value that is
// being used to populate the AttributeType. It is generally used to
// check the data format and ensure that it complies with the
// requirements of the AttributeType.
//
// TODO: don't use tfprotov6.Diagnostic, use our type
Validate(context.Context, tftypes.Value) []*tfprotov6.Diagnostic

// Description returns a practitioner-friendly explanation of the type
// and the constraints of the data it accepts and returns. It will be
// combined with the Description associated with the Attribute.
Description(context.Context, StringKind) string

// ValueFromTerraform returns an AttributeValue 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.
ValueFromTerraform(context.Context, tftypes.Value) (AttributeValue, error)
}

// StringKind represents a kind of string formatting.
type StringKind uint8

// NestingMode represents a specific way a group of attributes can be nested.
type NestingMode uint8

// AttributeValue defines an interface for describing data associated with an
// attribute. AttributeValues allow provider developers to specify data in a
// convenient format, and have it transparently be converted to formats
// Terraform understands.
type AttributeValue interface {
// ToTerraformValue returns the data contained in the AttributeValue as
// a Go type that tftypes.NewValue will accept.
ToTerraformValue(context.Context) (interface{}, error)

// Equal must return true if the AttributeValue is considered
// semantically equal to the AttributeValue passed as an argument.
Equal(AttributeValue) bool
}
14 changes: 7 additions & 7 deletions types/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package types
import (
"context"

tf "github.com/hashicorp/terraform-plugin-framework"
"github.com/hashicorp/terraform-plugin-framework/attribute"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/hashicorp/terraform-plugin-go/tftypes"
)

type ListType struct {
ElemType tf.AttributeType
ElemType attribute.AttributeType
}

// TerraformType returns the tftypes.Type that should be used to
Expand All @@ -36,14 +36,14 @@ func (l ListType) Validate(_ context.Context, _ tftypes.Value) []*tfprotov6.Diag
// Description returns a practitioner-friendly explanation of the type
// and the constraints of the data it accepts and returns. It will be
// combined with the Description associated with the Attribute.
func (l ListType) Description(_ context.Context, _ tf.StringKind) string {
func (l ListType) Description(_ context.Context, _ attribute.StringKind) string {
return ""
}

// ValueFromTerraform returns an AttributeValue 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 (l ListType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (tf.AttributeValue, error) {
func (l ListType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attribute.AttributeValue, error) {
if !in.IsKnown() {
return List{
Unknown: true,
Expand All @@ -59,7 +59,7 @@ func (l ListType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (tf.
if err != nil {
return nil, err
}
elems := make([]tf.AttributeValue, 0, len(val))
elems := make([]attribute.AttributeValue, 0, len(val))
for _, elem := range val {
av, err := l.ElemType.ValueFromTerraform(ctx, elem)
if err != nil {
Expand All @@ -76,7 +76,7 @@ func (l ListType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (tf.
type List struct {
Unknown bool
Null bool
Elems []tf.AttributeValue
Elems []attribute.AttributeValue
ElemType tftypes.Type
}

Expand Down Expand Up @@ -106,7 +106,7 @@ func (l List) ToTerraformValue(ctx context.Context) (interface{}, error) {

// Equal must return true if the AttributeValue is considered
// semantically equal to the AttributeValue passed as an argument.
func (l List) Equal(o tf.AttributeValue) bool {
func (l List) Equal(o attribute.AttributeValue) bool {
other, ok := o.(List)
if !ok {
return false
Expand Down
8 changes: 4 additions & 4 deletions types/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package types
import (
"context"

tf "github.com/hashicorp/terraform-plugin-framework"
"github.com/hashicorp/terraform-plugin-framework/attribute"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/hashicorp/terraform-plugin-go/tftypes"
)
Expand Down Expand Up @@ -32,14 +32,14 @@ func (s StringType) Validate(_ context.Context, _ tftypes.Value) []*tfprotov6.Di
// Description returns a practitioner-friendly explanation of the type
// and the constraints of the data it accepts and returns. It will be
// combined with the Description associated with the Attribute.
func (s StringType) Description(_ context.Context, _ tf.StringKind) string {
func (s StringType) Description(_ context.Context, _ attribute.StringKind) string {
return ""
}

// ValueFromTerraform returns an AttributeValue 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 (s StringType) ValueFromTerraform(_ context.Context, in tftypes.Value) (tf.AttributeValue, error) {
func (s StringType) ValueFromTerraform(_ context.Context, in tftypes.Value) (attribute.AttributeValue, error) {
var val String
if !in.IsKnown() {
val.Unknown = true
Expand Down Expand Up @@ -73,7 +73,7 @@ func (s String) ToTerraformValue(_ context.Context) (interface{}, error) {

// Equal must return true if the AttributeValue is considered
// semantically equal to the AttributeValue passed as an argument.
func (s String) Equal(other tf.AttributeValue) bool {
func (s String) Equal(other attribute.AttributeValue) bool {
o, ok := other.(String)
if !ok {
return false
Expand Down

0 comments on commit a31fc38

Please sign in to comment.