Skip to content

Commit

Permalink
Adding ValueFromFramework and ToFrameworkValue interface functions to…
Browse files Browse the repository at this point in the history
… types.SetType and types.Set (value), respectively (#535)
  • Loading branch information
bendbennett committed Nov 11, 2022
1 parent 467f056 commit 94d03e6
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 20 deletions.
6 changes: 3 additions & 3 deletions internal/fwserver/attr_value.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@ func coerceObjectValue(schemaPath path.Path, value attr.Value) (types.Object, di
return object, nil
}

func coerceSetValue(schemaPath path.Path, value attr.Value) (types.Set, diag.Diagnostics) {
set, ok := value.(types.Set)
func coerceSetValue(ctx context.Context, schemaPath path.Path, value attr.Value) (types.Set, diag.Diagnostics) {
setVal, ok := value.(types.SetVal)

if !ok {
return types.SetNull(nil), diag.Diagnostics{
attributePlanModificationWalkError(schemaPath, value),
}
}

return set, nil
return setVal.ToFrameworkValue(ctx)
}

func listElemObject(ctx context.Context, schemaPath path.Path, list types.List, index int, description fwschemadata.DataDescription) (types.Object, diag.Diagnostics) {
Expand Down
6 changes: 3 additions & 3 deletions internal/fwserver/attribute_plan_modification.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,23 +220,23 @@ func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.Mo
return
}
case fwschema.NestingModeSet:
configSet, diags := coerceSetValue(req.AttributePath, req.AttributeConfig)
configSet, diags := coerceSetValue(ctx, req.AttributePath, req.AttributeConfig)

resp.Diagnostics.Append(diags...)

if resp.Diagnostics.HasError() {
return
}

planSet, diags := coerceSetValue(req.AttributePath, req.AttributePlan)
planSet, diags := coerceSetValue(ctx, req.AttributePath, req.AttributePlan)

resp.Diagnostics.Append(diags...)

if resp.Diagnostics.HasError() {
return
}

stateSet, diags := coerceSetValue(req.AttributePath, req.AttributeState)
stateSet, diags := coerceSetValue(ctx, req.AttributePath, req.AttributeState)

resp.Diagnostics.Append(diags...)

Expand Down
13 changes: 10 additions & 3 deletions internal/fwserver/attribute_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,19 +177,26 @@ func AttributeValidateNestedAttributes(ctx context.Context, a fwschema.Attribute
}
}
case fwschema.NestingModeSet:
s, ok := req.AttributeConfig.(types.Set)
setVal, ok := req.AttributeConfig.(types.SetVal)

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",
"Attribute validation cannot walk schema. Report this to the provider developer:\n\n"+err.Error(),
"Attribute Validation Error Invalid Value Type",
"A type from which a types.Set can be obtained is expected here. Report this to the provider developer:\n\n"+err.Error(),
)

return
}

s, diags := setVal.ToFrameworkValue(ctx)

resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

for _, value := range s.Elements() {
for nestedName, nestedAttr := range a.GetAttributes().GetAttributes() {
nestedAttrReq := tfsdk.ValidateAttributeRequest{
Expand Down
6 changes: 3 additions & 3 deletions internal/fwserver/block_plan_modification.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,23 +236,23 @@ func BlockModifyPlan(ctx context.Context, b fwschema.Block, req tfsdk.ModifyAttr
return
}
case fwschema.BlockNestingModeSet:
configSet, diags := coerceSetValue(req.AttributePath, req.AttributeConfig)
configSet, diags := coerceSetValue(ctx, req.AttributePath, req.AttributeConfig)

resp.Diagnostics.Append(diags...)

if resp.Diagnostics.HasError() {
return
}

planSet, diags := coerceSetValue(req.AttributePath, req.AttributePlan)
planSet, diags := coerceSetValue(ctx, req.AttributePath, req.AttributePlan)

resp.Diagnostics.Append(diags...)

if resp.Diagnostics.HasError() {
return
}

stateSet, diags := coerceSetValue(req.AttributePath, req.AttributeState)
stateSet, diags := coerceSetValue(ctx, req.AttributePath, req.AttributeState)

resp.Diagnostics.Append(diags...)

Expand Down
15 changes: 11 additions & 4 deletions internal/fwserver/block_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,19 +124,26 @@ 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:
s, ok := req.AttributeConfig.(types.Set)
setVal, ok := req.AttributeConfig.(types.SetVal)

if !ok {
err := fmt.Errorf("unknown block value type (%s) for nesting mode (%T) at path: %s", req.AttributeConfig.Type(ctx), nm, req.AttributePath)
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",
"Block validation cannot walk schema. Report this to the provider developer:\n\n"+err.Error(),
"Block Validation Error Invalid Value Type",
"A type from which a types.Set can be obtained is expected here. Report this to the provider developer:\n\n"+err.Error(),
)

return
}

s, diags := setVal.ToFrameworkValue(ctx)

resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

for _, value := range s.Elements() {
for name, attr := range b.GetAttributes() {
nestedAttrReq := tfsdk.ValidateAttributeRequest{
Expand Down
30 changes: 26 additions & 4 deletions types/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,23 @@ import (
)

var (
_ attr.Type = SetType{}
_ SetTyp = SetType{}
_ xattr.TypeWithValidate = SetType{}
_ attr.Value = &Set{}
_ SetVal = &Set{}
)

type SetTyp interface {
attr.Type

ValueFromFramework(context.Context, Set) (attr.Value, diag.Diagnostics)
}

type SetVal interface {
attr.Value

ToFrameworkValue(ctx context.Context) (Set, diag.Diagnostics)
}

// SetType is an AttributeType representing a set of values. All values must
// be of the same type, which the provider must specify as the ElemType
// property.
Expand Down Expand Up @@ -191,12 +203,17 @@ func (st SetType) Validate(ctx context.Context, in tftypes.Value, path path.Path
}

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

// ValueFromFramework returns an attr.Value given a Set.
func (st SetType) ValueFromFramework(_ context.Context, set Set) (attr.Value, diag.Diagnostics) {
return set, nil
}

// 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) Set {
Expand Down Expand Up @@ -467,3 +484,8 @@ func (s Set) String() string {

return res.String()
}

// ToFrameworkValue returns the Set.
func (s Set) ToFrameworkValue(context.Context) (Set, diag.Diagnostics) {
return s, nil
}

0 comments on commit 94d03e6

Please sign in to comment.