Skip to content

Commit 00d6c85

Browse files
author
Ivan De Marino
committed
Adding OneOf() and NoneOf() validators, a pair for each type.
The underlying implementation sits in `primitivevalidator` package.
1 parent 783ec01 commit 00d6c85

File tree

20 files changed

+1090
-7
lines changed

20 files changed

+1090
-7
lines changed

.changelog/42.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
```release-note:enhancement
2+
floatvalidator: 2 new validation functions, `OneOf()` and `NoneOf()`
3+
```
4+
5+
```release-note:enhancement
6+
int64validator: 2 new validation functions, `OneOf()` and `NoneOf()`
7+
```
8+
9+
```release-note:feature
10+
numbervalidator: New package that starts with 2 validation functions, `OneOf()` and `NoneOf()`
11+
```
12+
13+
```release-note:enhancement
14+
stringvalidator: 2 new validation functions, `OneOf()` and `NoneOf()`, similar to the ones in `genericvalidator` but option to control case-sensitivity
15+
```
16+
17+
```release-note:note
18+
Introduced a new package `primitivevalidator`, holding the shared code used by type-specific validators (ex. `OneOf()` and `NoneOf()`)
19+
```

float64validator/none_of.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package float64validator
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-framework-validators/primitivevalidator"
5+
"github.com/hashicorp/terraform-plugin-framework/attr"
6+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
7+
"github.com/hashicorp/terraform-plugin-framework/types"
8+
)
9+
10+
// NoneOf checks that the float64 held in the attribute
11+
// is none of the given `unacceptableFloats`.
12+
func NoneOf(unacceptableFloats ...float64) tfsdk.AttributeValidator {
13+
unacceptableFloatValues := make([]attr.Value, 0, len(unacceptableFloats))
14+
for _, f := range unacceptableFloats {
15+
unacceptableFloatValues = append(unacceptableFloatValues, types.Float64{Value: f})
16+
}
17+
18+
return primitivevalidator.NoneOf(unacceptableFloatValues...)
19+
}

float64validator/one_of.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package float64validator
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-framework-validators/primitivevalidator"
5+
"github.com/hashicorp/terraform-plugin-framework/attr"
6+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
7+
"github.com/hashicorp/terraform-plugin-framework/types"
8+
)
9+
10+
// OneOf checks that the float64 held in the attribute
11+
// is one of the given `acceptableFloats`.
12+
func OneOf(acceptableFloats ...float64) tfsdk.AttributeValidator {
13+
acceptableFloatValues := make([]attr.Value, 0, len(acceptableFloats))
14+
for _, f := range acceptableFloats {
15+
acceptableFloatValues = append(acceptableFloatValues, types.Float64{Value: f})
16+
}
17+
18+
return primitivevalidator.OneOf(acceptableFloatValues...)
19+
}

int64validator/none_of.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package int64validator
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-framework-validators/primitivevalidator"
5+
"github.com/hashicorp/terraform-plugin-framework/attr"
6+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
7+
"github.com/hashicorp/terraform-plugin-framework/types"
8+
)
9+
10+
// NoneOf checks that the int64 held in the attribute
11+
// is none of the given `unacceptableInts`.
12+
func NoneOf(unacceptableInts ...int64) tfsdk.AttributeValidator {
13+
unacceptableIntValues := make([]attr.Value, 0, len(unacceptableInts))
14+
for _, i := range unacceptableInts {
15+
unacceptableIntValues = append(unacceptableIntValues, types.Int64{Value: i})
16+
}
17+
18+
return primitivevalidator.NoneOf(unacceptableIntValues...)
19+
}

int64validator/one_of.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package int64validator
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-framework-validators/primitivevalidator"
5+
"github.com/hashicorp/terraform-plugin-framework/attr"
6+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
7+
"github.com/hashicorp/terraform-plugin-framework/types"
8+
)
9+
10+
// OneOf checks that the int64 held in the attribute
11+
// is one of the given `acceptableInts`.
12+
func OneOf(acceptableInts ...int64) tfsdk.AttributeValidator {
13+
acceptableIntValues := make([]attr.Value, 0, len(acceptableInts))
14+
for _, i := range acceptableInts {
15+
acceptableIntValues = append(acceptableIntValues, types.Int64{Value: i})
16+
}
17+
18+
return primitivevalidator.OneOf(acceptableIntValues...)
19+
}

numbervalidator/doc.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Package numbervalidator provides validators for types.Number attributes.
2+
package numbervalidator

numbervalidator/none_of.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package numbervalidator
2+
3+
import (
4+
"math/big"
5+
6+
"github.com/hashicorp/terraform-plugin-framework-validators/primitivevalidator"
7+
"github.com/hashicorp/terraform-plugin-framework/attr"
8+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
)
11+
12+
// NoneOf checks that the *big.Float held in the attribute
13+
// is none of the given `unacceptableFloats`.
14+
func NoneOf(unacceptableFloats ...*big.Float) tfsdk.AttributeValidator {
15+
unacceptableFloatValues := make([]attr.Value, 0, len(unacceptableFloats))
16+
for _, f := range unacceptableFloats {
17+
unacceptableFloatValues = append(unacceptableFloatValues, types.Number{Value: f})
18+
}
19+
20+
return primitivevalidator.NoneOf(unacceptableFloatValues...)
21+
}

numbervalidator/one_of.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package numbervalidator
2+
3+
import (
4+
"math/big"
5+
6+
"github.com/hashicorp/terraform-plugin-framework-validators/primitivevalidator"
7+
"github.com/hashicorp/terraform-plugin-framework/attr"
8+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
)
11+
12+
// OneOf checks that the *big.Float held in the attribute
13+
// is one of the given `acceptableFloats`.
14+
func OneOf(acceptableFloats ...*big.Float) tfsdk.AttributeValidator {
15+
acceptableFloatValues := make([]attr.Value, 0, len(acceptableFloats))
16+
for _, f := range acceptableFloats {
17+
acceptableFloatValues = append(acceptableFloatValues, types.Number{Value: f})
18+
}
19+
20+
return primitivevalidator.OneOf(acceptableFloatValues...)
21+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package primitivevalidator
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
8+
"github.com/hashicorp/terraform-plugin-framework/attr"
9+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
10+
"github.com/hashicorp/terraform-plugin-framework/types"
11+
)
12+
13+
// acceptablePrimitiveValuesAttributeValidator is the underlying struct implementing OneOf and NoneOf.
14+
type acceptablePrimitiveValuesAttributeValidator struct {
15+
acceptableValues []attr.Value
16+
shouldMatch bool
17+
}
18+
19+
var _ tfsdk.AttributeValidator = (*acceptablePrimitiveValuesAttributeValidator)(nil)
20+
21+
func (av *acceptablePrimitiveValuesAttributeValidator) Description(ctx context.Context) string {
22+
return av.MarkdownDescription(ctx)
23+
}
24+
25+
func (av *acceptablePrimitiveValuesAttributeValidator) MarkdownDescription(_ context.Context) string {
26+
if av.shouldMatch {
27+
return fmt.Sprintf("Value must be one of: %q", av.acceptableValues)
28+
} else {
29+
return fmt.Sprintf("Value must be none of: %q", av.acceptableValues)
30+
}
31+
32+
}
33+
34+
func (av *acceptablePrimitiveValuesAttributeValidator) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, res *tfsdk.ValidateAttributeResponse) {
35+
if req.AttributeConfig.IsNull() || req.AttributeConfig.IsUnknown() {
36+
return
37+
}
38+
39+
var value attr.Value
40+
switch typedAttributeConfig := req.AttributeConfig.(type) {
41+
case types.String, types.Bool, types.Int64, types.Float64, types.Number:
42+
value = typedAttributeConfig
43+
default:
44+
res.Diagnostics.AddAttributeError(
45+
req.AttributePath,
46+
"This validator should be used against primitive types (String, Bool, Number, Int64, Float64).",
47+
"This is always indicative of a bug within the provider.",
48+
)
49+
return
50+
}
51+
52+
if av.shouldMatch && !av.isAcceptableValue(value) || //< EITHER should match but it does not
53+
!av.shouldMatch && av.isAcceptableValue(value) { //< OR should not match but it does
54+
res.Diagnostics.Append(validatordiag.InvalidValueMatchDiagnostic(
55+
req.AttributePath,
56+
av.Description(ctx),
57+
value.String(),
58+
))
59+
}
60+
}
61+
62+
func (av *acceptablePrimitiveValuesAttributeValidator) isAcceptableValue(v attr.Value) bool {
63+
for _, acceptableV := range av.acceptableValues {
64+
if v.Equal(acceptableV) {
65+
return true
66+
}
67+
}
68+
69+
return false
70+
}

primitivevalidator/doc.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Package primitivevalidator provides validators for attributes
2+
// of "primitive" type (i.e. `types.String`, `types.Number`, `types.Int64`,
3+
// `types.Float64` and `types.Bool`).
4+
package primitivevalidator

primitivevalidator/none_of.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package primitivevalidator
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-framework/attr"
5+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
6+
)
7+
8+
// NoneOf checks that the value held in the attribute
9+
// is none of the given `unacceptableValues`.
10+
//
11+
// This validator can be used only against primitives like
12+
// `types.String`, `types.Number`, `types.Int64`,
13+
// `types.Float64` and `types.Bool`.
14+
func NoneOf(unacceptableValues ...attr.Value) tfsdk.AttributeValidator {
15+
return &acceptablePrimitiveValuesAttributeValidator{
16+
acceptableValues: unacceptableValues,
17+
shouldMatch: false,
18+
}
19+
}

0 commit comments

Comments
 (0)