attr/xattr: Consider Deprecating tftypes.Value Handling In Preference of attr.Value Handling
Module version
v1.0.0
Use-cases
Provider developers should not need to drop down to the github.com/hashicorp/terraform-plugin-go/tftypes type system when creating custom types via attr.Value with validation. In particular:
attr/xattr.TypeWithValidate
-
Validate(context.Context, tftypes.Value, path.Path) diag.Diagnostics
Attempted Solutions
Proposal
Similar to the framework type system specific types/basetypes package interfaces, such as StringTypable/StringValuable, introduce validation interfaces that are based on the framework types. Potentially a new types/validation package. The types/basetypes package cannot be used as diag.Diagnostics has a dependency on basetypes.SetValue.
The existing attr/xattr.TypeWithValidate interface and its Validate method would be deprecated, instead encouraging the usage of the new interfaces. The attr/xattr package cannot be removed until the next major version due to compatibility promises.
Proposed types/validation package:
package validation
type Bool interface {
basetypes.BoolValuable
ValidateBool(context.Context, BoolRequest, *BoolResponse)
}
type Float64 interface {
basetypes.Float64Valuable
ValidateFloat64(context.Context, Float64Request, *Float64Response)
}
type Int64 interface {
basetypes.Int64Valuable
ValidateInt64(context.Context, Int64Request, *Int64Response)
}
type List interface {
basetypes.ListValuable
ValidateList(context.Context, ListRequest, *ListResponse)
}
type Map interface {
basetypes.MapValuable
ValidateMap(context.Context, MapRequest, *MapResponse)
}
type Number interface {
basetypes.NumberValuable
ValidateNumber(context.Context, NumberRequest, *NumberResponse)
}
type Object interface {
basetypes.ObjectValuable
ValidateObject(context.Context, ObjectRequest, *ObjectResponse)
}
type Set interface {
basetypes.SetValuable
ValidateSet(context.Context, SetRequest, *SetResponse)
}
type String interface {
basetypes.StringValuable
ValidateString(context.Context, StringRequest, *StringResponse)
}
Note this proposal switches implementation to a request/response pattern similar to other framework handling so that future changes to the requests/responses can be done without updates to the interfaces themselves. Those types can be fairly straightforward for now to match the existing handling:
type BoolRequest struct {
Path path.Path
Value basetypes.BoolValue
}
type BoolResponse struct {
Diagnostics diag.Diagnostics
}
Inside the framework where the attr/xattr.TypeWithValidate interface is referenced will need to be switched to a type switch, e.g.
switch xxx.(type) {
case xattr.TypeWithValidate:
// existing tftypes handling
case validation.Bool:
// use basetypes.BoolValuable interface get basetypes.BoolValue
// call ValidateBool() and handle diagnostics
// ... other type cases ...
}
References
- #172
- #588
This issue is a little more poignant now that we are trying to introduce functions, where function argument data has an argument position instead of a path. Might be a good time to fix this.
@bendbennett should we create a v2.0.0 issue to remove the deprecated bits?
v2.0.0 issue to remove the deprecated xattr.TypeWithValidate - https://github.com/hashicorp/terraform-plugin-framework/issues/978
Awesome!!
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.