Skip to content

Commit

Permalink
Refactoring customize diff funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
bendbennett committed Jun 3, 2022
1 parent f474cf8 commit 24746bd
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 35 deletions.
13 changes: 7 additions & 6 deletions internal/provider/resource_password.go
Expand Up @@ -11,10 +11,14 @@ import (
)

// resourcePassword and resourceString both use the same set of CustomizeDiffFunc(s) in order to handle the deprecation
// of the `number` attribute and the simultaneous addition of the `numeric` attribute. customDiffIfValue handles
// of the `number` attribute and the simultaneous addition of the `numeric` attribute. planDefaultIfAllNull handles
// ensuring that both `number` and `numeric` default to `true` when they are both absent from config.
// customDiffIfValueChange handles keeping number and numeric in-sync when either one has been changed.
// planSyncIfChange handles keeping number and numeric in-sync when either one has been changed.
func resourcePassword() *schema.Resource {
customizeDiffFuncs := planDefaultIfAllNull(true, "number", "numeric")
customizeDiffFuncs = append(customizeDiffFuncs, planSyncIfChange("number", "numeric"))
customizeDiffFuncs = append(customizeDiffFuncs, planSyncIfChange("numeric", "number"))

return &schema.Resource{
Description: "Identical to [random_string](string.html) with the exception that the result is " +
"treated as sensitive and, thus, _not_ displayed in console output. Read more about sensitive " +
Expand Down Expand Up @@ -42,10 +46,7 @@ func resourcePassword() *schema.Resource {
},
},
CustomizeDiff: customdiff.All(
customDiffIfValue("number"),
customDiffIfValue("numeric"),
customDiffIfValueChange("number", "numeric"),
customDiffIfValueChange("numeric", "number"),
customizeDiffFuncs...,
),
}
}
Expand Down
13 changes: 7 additions & 6 deletions internal/provider/resource_string.go
Expand Up @@ -9,10 +9,14 @@ import (
)

// resourceString and resourcePassword both use the same set of CustomizeDiffFunc(s) in order to handle the deprecation
// of the `number` attribute and the simultaneous addition of the `numeric` attribute. customDiffIfValue handles
// of the `number` attribute and the simultaneous addition of the `numeric` attribute. planDefaultIfAllNull handles
// ensuring that both `number` and `numeric` default to `true` when they are both absent from config.
// customDiffIfValueChange handles keeping number and numeric in-sync when either one has been changed.
// planSyncIfChange handles keeping number and numeric in-sync when either one has been changed.
func resourceString() *schema.Resource {
customizeDiffFuncs := planDefaultIfAllNull(true, "number", "numeric")
customizeDiffFuncs = append(customizeDiffFuncs, planSyncIfChange("number", "numeric"))
customizeDiffFuncs = append(customizeDiffFuncs, planSyncIfChange("numeric", "number"))

return &schema.Resource{
Description: "The resource `random_string` generates a random permutation of alphanumeric " +
"characters and optionally special characters.\n" +
Expand Down Expand Up @@ -41,10 +45,7 @@ func resourceString() *schema.Resource {
},
},
CustomizeDiff: customdiff.All(
customDiffIfValue("number"),
customDiffIfValue("numeric"),
customDiffIfValueChange("number", "numeric"),
customDiffIfValueChange("numeric", "number"),
customizeDiffFuncs...,
),
}
}
Expand Down
64 changes: 41 additions & 23 deletions internal/provider/string.go
Expand Up @@ -6,6 +6,7 @@ package provider
import (
"context"
"crypto/rand"
"errors"
"fmt"
"math/big"
"sort"
Expand Down Expand Up @@ -340,36 +341,53 @@ func resourceStateUpgradeAddNumeric(resourceName string) func(_ context.Context,
}
}

// customDiffIfValue handles ensuring that both `number` and `numeric` attributes default to `true` when neither are set
// planDefaultIfAllNull handles ensuring that both `number` and `numeric` attributes default to `true` when neither are set
// in the config and, they had been previously set to `false`. This behaviour mimics setting `Default: true` on the
// attributes. Usage of `Default` is avoided as `Default` cannot be used with CustomizeDiffFunc(s) which are required in
// order to keep `number` and `numeric` in-sync (see customDiffIfValueChange).
func customDiffIfValue(key string) func(context.Context, *schema.ResourceDiff, interface{}) error {
return customdiff.IfValue(
key,
func(ctx context.Context, value, meta interface{}) bool {
return !value.(bool)
},
func(_ context.Context, d *schema.ResourceDiff, _ interface{}) error {
vm := d.GetRawConfig().AsValueMap()
if vm["number"].IsNull() && vm["numeric"].IsNull() {
err := d.SetNew("number", true)
if err != nil {
return err
// order to keep `number` and `numeric` in-sync (see planSyncIfChange).
func planDefaultIfAllNull(defaultVal interface{}, keys ...string) []schema.CustomizeDiffFunc {
var result []schema.CustomizeDiffFunc

for _, key := range keys {
result = append(result, customdiff.IfValue(
key,
func(ctx context.Context, value, meta interface{}) bool {
return !value.(bool)
},
func(_ context.Context, d *schema.ResourceDiff, _ interface{}) error {
vm := d.GetRawConfig().AsValueMap()

number, ok := vm["number"]
if !ok {
return errors.New("number is absent from raw config")
}
err = d.SetNew("numeric", true)
if err != nil {
return err

numeric, ok := vm["numeric"]
if !ok {
return errors.New("numeric is absent from raw config")
}
}
return nil
},
)

if number.IsNull() && numeric.IsNull() {
err := d.SetNew("number", defaultVal)
if err != nil {
return err
}
err = d.SetNew("numeric", defaultVal)
if err != nil {
return err
}
}
return nil
},
))
}

return result
}

// customDiffIfValueChange handles keeping `number` and `numeric` in-sync. If either is changed the value of both is
// planSyncIfChange handles keeping `number` and `numeric` in-sync. If either is changed the value of both is
// set to the new value of the attribute that has changed.
func customDiffIfValueChange(key, keyToSync string) func(context.Context, *schema.ResourceDiff, interface{}) error {
func planSyncIfChange(key, keyToSync string) func(context.Context, *schema.ResourceDiff, interface{}) error {
return customdiff.IfValueChange(
key,
func(ctx context.Context, oldValue, newValue, meta interface{}) bool {
Expand Down

0 comments on commit 24746bd

Please sign in to comment.