Skip to content

Commit

Permalink
attr: Add ValueType method to Type interface
Browse files Browse the repository at this point in the history
Reference: #496

This will allow the internal reflection package to return better error diagnostics.
  • Loading branch information
bflad committed Sep 23, 2022
1 parent 123c67f commit f7f4091
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .changelog/pending.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:breaking-change
attr: The `Type` interface now requires the `ValueType` method, which is used for enhancing error diagnostics from the framework
```

```release-note:enhancement
internal/reflect: Added `attr.Value` type suggestions to error diagnostics
```
6 changes: 6 additions & 0 deletions attr/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ type Type interface {
// for the provider to consume the data with.
ValueFromTerraform(context.Context, tftypes.Value) (Value, error)

// ValueType should return the attr.Value type returned by
// ValueFromTerraform. The returned attr.Value can be any null, unknown,
// or known value for the type, as this is intended for type detection
// and improving error diagnostics.
ValueType(context.Context) Value

// Equal must return true if the Type is considered semantically equal
// to the Type passed as an argument.
Equal(Type) bool
Expand Down
5 changes: 5 additions & 0 deletions internal/testing/types/bool.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ func (t BoolType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (att
return Bool{Bool: types.Bool{Value: b}, CreatedBy: t}, nil
}

// ValueType returns the Value type.
func (t BoolType) ValueType(_ context.Context) attr.Value {
return Bool{}
}

type Bool struct {
types.Bool

Expand Down
5 changes: 5 additions & 0 deletions internal/testing/types/invalid.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ func (t InvalidType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (
return nil, fmt.Errorf("intentional ValueFromTerraform error")
}

// ValueType returns the Value type.
func (t InvalidType) ValueType(_ context.Context) attr.Value {
return Invalid{}
}

// Invalid is an attr.Value that returns errors for methods than can return errors.
type Invalid struct{}

Expand Down
5 changes: 5 additions & 0 deletions internal/testing/types/number.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ func (t NumberType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (a
}, nil
}

// ValueType returns the Value type.
func (t NumberType) ValueType(_ context.Context) attr.Value {
return Number{}
}

type Number struct {
types.Number

Expand Down
5 changes: 5 additions & 0 deletions internal/testing/types/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ func (t StringType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (a
}, nil
}

// ValueType returns the Value type.
func (t StringType) ValueType(_ context.Context) attr.Value {
return String{}
}

type String struct {
InternalString types.String

Expand Down
7 changes: 7 additions & 0 deletions types/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ func (l ListType) Validate(ctx context.Context, in tftypes.Value, path path.Path
return diags
}

// ValueType returns the Value type.
func (t ListType) ValueType(_ context.Context) attr.Value {
return List{
ElemType: t.ElemType,
}
}

// List represents a list of attr.Values, all of the same type, indicated
// by ElemType.
type List struct {
Expand Down
7 changes: 7 additions & 0 deletions types/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ func (m MapType) Validate(ctx context.Context, in tftypes.Value, path path.Path)
return diags
}

// ValueType returns the Value type.
func (t MapType) ValueType(_ context.Context) attr.Value {
return Map{
ElemType: t.ElemType,
}
}

// Map represents a map of attr.Values, all of the same type, indicated by
// ElemType. Keys for the map will always be strings.
type Map struct {
Expand Down
7 changes: 7 additions & 0 deletions types/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,13 @@ func (o ObjectType) String() string {
return res.String()
}

// ValueType returns the Value type.
func (t ObjectType) ValueType(_ context.Context) attr.Value {
return Object{
AttrTypes: t.AttrTypes,
}
}

// Object represents an object
type Object struct {
// Unknown will be set to true if the entire object is an unknown value.
Expand Down
19 changes: 19 additions & 0 deletions types/primitive.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,25 @@ func (p primitive) ValueFromTerraform(ctx context.Context, in tftypes.Value) (at
}
}

// 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 {
Expand Down
5 changes: 5 additions & 0 deletions types/primitive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ 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()

Expand Down
7 changes: 7 additions & 0 deletions types/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ func (st SetType) Validate(ctx context.Context, in tftypes.Value, path path.Path
return diags
}

// ValueType returns the Value type.
func (t SetType) ValueType(_ context.Context) attr.Value {
return Set{
ElemType: t.ElemType,
}
}

// Set represents a set of attr.Value, all of the same type,
// indicated by ElemType.
type Set struct {
Expand Down

0 comments on commit f7f4091

Please sign in to comment.