Skip to content

Commit 0438916

Browse files
committed
setvalidator: implement parameter interface
1 parent 68b58e1 commit 0438916

10 files changed

+175
-23
lines changed

setvalidator/doc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright (c) HashiCorp, Inc.
22
// SPDX-License-Identifier: MPL-2.0
33

4-
// Package setvalidator provides validators for types.Set attributes.
4+
// Package setvalidator provides validators for types.Set attributes and function parameters.
55
package setvalidator

setvalidator/size_at_least.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,28 @@ import (
77
"context"
88
"fmt"
99

10+
"github.com/hashicorp/terraform-plugin-framework/function"
1011
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1112

1213
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
14+
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatorfuncerr"
1315
)
1416

1517
var _ validator.Set = sizeAtLeastValidator{}
18+
var _ function.SetParameterValidator = sizeAtLeastValidator{}
1619

17-
// sizeAtLeastValidator validates that set contains at least min elements.
1820
type sizeAtLeastValidator struct {
1921
min int
2022
}
2123

22-
// Description describes the validation in plain text formatting.
2324
func (v sizeAtLeastValidator) Description(_ context.Context) string {
2425
return fmt.Sprintf("set must contain at least %d elements", v.min)
2526
}
2627

27-
// MarkdownDescription describes the validation in Markdown formatting.
2828
func (v sizeAtLeastValidator) MarkdownDescription(ctx context.Context) string {
2929
return v.Description(ctx)
3030
}
3131

32-
// Validate performs the validation.
3332
func (v sizeAtLeastValidator) ValidateSet(ctx context.Context, req validator.SetRequest, resp *validator.SetResponse) {
3433
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
3534
return
@@ -46,14 +45,30 @@ func (v sizeAtLeastValidator) ValidateSet(ctx context.Context, req validator.Set
4645
}
4746
}
4847

48+
func (v sizeAtLeastValidator) ValidateParameterSet(ctx context.Context, req function.SetParameterValidatorRequest, resp *function.SetParameterValidatorResponse) {
49+
if req.Value.IsNull() || req.Value.IsUnknown() {
50+
return
51+
}
52+
53+
elems := req.Value.Elements()
54+
55+
if len(elems) < v.min {
56+
resp.Error = validatorfuncerr.InvalidParameterValueFuncError(
57+
req.ArgumentPosition,
58+
v.Description(ctx),
59+
fmt.Sprintf("%d", len(elems)),
60+
)
61+
}
62+
}
63+
4964
// SizeAtLeast returns an AttributeValidator which ensures that any configured
50-
// attribute value:
65+
// attribute or function parameter value:
5166
//
5267
// - Is a Set.
5368
// - Contains at least min elements.
5469
//
5570
// Null (unconfigured) and unknown (known after apply) values are skipped.
56-
func SizeAtLeast(minVal int) validator.Set {
71+
func SizeAtLeast(minVal int) sizeAtLeastValidator {
5772
return sizeAtLeastValidator{
5873
min: minVal,
5974
}

setvalidator/size_at_least_example_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package setvalidator_test
66
import (
77
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
88
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
9+
"github.com/hashicorp/terraform-plugin-framework/function"
910
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1011
"github.com/hashicorp/terraform-plugin-framework/types"
1112
)
@@ -25,3 +26,17 @@ func ExampleSizeAtLeast() {
2526
},
2627
}
2728
}
29+
30+
func ExampleSizeAtLeast_function() {
31+
_ = function.Definition{
32+
Parameters: []function.Parameter{
33+
function.SetParameter{
34+
Name: "example_param",
35+
Validators: []function.SetParameterValidator{
36+
// Validate this set must contain at least 2 elements.
37+
setvalidator.SizeAtLeast(2),
38+
},
39+
},
40+
},
41+
}
42+
}

setvalidator/size_at_least_test.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ package setvalidator
55

66
import (
77
"context"
8+
"fmt"
89
"testing"
910

1011
"github.com/hashicorp/terraform-plugin-framework/attr"
12+
"github.com/hashicorp/terraform-plugin-framework/function"
1113
"github.com/hashicorp/terraform-plugin-framework/path"
1214
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1315
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -67,7 +69,8 @@ func TestSizeAtLeastValidator(t *testing.T) {
6769

6870
for name, test := range tests {
6971
name, test := name, test
70-
t.Run(name, func(t *testing.T) {
72+
73+
t.Run(fmt.Sprintf("ValidateSet - %s", name), func(t *testing.T) {
7174
t.Parallel()
7275
request := validator.SetRequest{
7376
Path: path.Root("test"),
@@ -85,5 +88,23 @@ func TestSizeAtLeastValidator(t *testing.T) {
8588
t.Fatalf("got unexpected error: %s", response.Diagnostics)
8689
}
8790
})
91+
92+
t.Run(fmt.Sprintf("ValidateParameterSet - %s", name), func(t *testing.T) {
93+
t.Parallel()
94+
request := function.SetParameterValidatorRequest{
95+
ArgumentPosition: 0,
96+
Value: test.val,
97+
}
98+
response := function.SetParameterValidatorResponse{}
99+
SizeAtLeast(test.min).ValidateParameterSet(context.TODO(), request, &response)
100+
101+
if response.Error == nil && test.expectError {
102+
t.Fatal("expected error, got no error")
103+
}
104+
105+
if response.Error != nil && !test.expectError {
106+
t.Fatalf("got unexpected error: %s", response.Error)
107+
}
108+
})
88109
}
89110
}

setvalidator/size_at_most.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,28 @@ import (
77
"context"
88
"fmt"
99

10+
"github.com/hashicorp/terraform-plugin-framework/function"
1011
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1112

1213
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
14+
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatorfuncerr"
1315
)
1416

1517
var _ validator.Set = sizeAtMostValidator{}
18+
var _ function.SetParameterValidator = sizeAtMostValidator{}
1619

17-
// sizeAtMostValidator validates that set contains at most max elements.
1820
type sizeAtMostValidator struct {
1921
max int
2022
}
2123

22-
// Description describes the validation in plain text formatting.
2324
func (v sizeAtMostValidator) Description(_ context.Context) string {
2425
return fmt.Sprintf("set must contain at most %d elements", v.max)
2526
}
2627

27-
// MarkdownDescription describes the validation in Markdown formatting.
2828
func (v sizeAtMostValidator) MarkdownDescription(ctx context.Context) string {
2929
return v.Description(ctx)
3030
}
3131

32-
// Validate performs the validation.
3332
func (v sizeAtMostValidator) ValidateSet(ctx context.Context, req validator.SetRequest, resp *validator.SetResponse) {
3433
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
3534
return
@@ -46,14 +45,30 @@ func (v sizeAtMostValidator) ValidateSet(ctx context.Context, req validator.SetR
4645
}
4746
}
4847

48+
func (v sizeAtMostValidator) ValidateParameterSet(ctx context.Context, req function.SetParameterValidatorRequest, resp *function.SetParameterValidatorResponse) {
49+
if req.Value.IsNull() || req.Value.IsUnknown() {
50+
return
51+
}
52+
53+
elems := req.Value.Elements()
54+
55+
if len(elems) > v.max {
56+
resp.Error = validatorfuncerr.InvalidParameterValueFuncError(
57+
req.ArgumentPosition,
58+
v.Description(ctx),
59+
fmt.Sprintf("%d", len(elems)),
60+
)
61+
}
62+
}
63+
4964
// SizeAtMost returns an AttributeValidator which ensures that any configured
50-
// attribute value:
65+
// attribute or function parameter value:
5166
//
5267
// - Is a Set.
5368
// - Contains at most max elements.
5469
//
5570
// Null (unconfigured) and unknown (known after apply) values are skipped.
56-
func SizeAtMost(maxVal int) validator.Set {
71+
func SizeAtMost(maxVal int) sizeAtMostValidator {
5772
return sizeAtMostValidator{
5873
max: maxVal,
5974
}

setvalidator/size_at_most_example_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package setvalidator_test
66
import (
77
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
88
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
9+
"github.com/hashicorp/terraform-plugin-framework/function"
910
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1011
"github.com/hashicorp/terraform-plugin-framework/types"
1112
)
@@ -25,3 +26,17 @@ func ExampleSizeAtMost() {
2526
},
2627
}
2728
}
29+
30+
func ExampleSizeAtMost_function() {
31+
_ = function.Definition{
32+
Parameters: []function.Parameter{
33+
function.SetParameter{
34+
Name: "example_param",
35+
Validators: []function.SetParameterValidator{
36+
// Validate this set must contain at most 2 elements.
37+
setvalidator.SizeAtMost(2),
38+
},
39+
},
40+
},
41+
}
42+
}

setvalidator/size_at_most_test.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ package setvalidator
55

66
import (
77
"context"
8+
"fmt"
89
"testing"
910

1011
"github.com/hashicorp/terraform-plugin-framework/attr"
12+
"github.com/hashicorp/terraform-plugin-framework/function"
1113
"github.com/hashicorp/terraform-plugin-framework/path"
1214
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1315
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -71,7 +73,8 @@ func TestSizeAtMostValidator(t *testing.T) {
7173

7274
for name, test := range tests {
7375
name, test := name, test
74-
t.Run(name, func(t *testing.T) {
76+
77+
t.Run(fmt.Sprintf("ValidateSet - %s", name), func(t *testing.T) {
7578
t.Parallel()
7679
request := validator.SetRequest{
7780
Path: path.Root("test"),
@@ -89,5 +92,23 @@ func TestSizeAtMostValidator(t *testing.T) {
8992
t.Fatalf("got unexpected error: %s", response.Diagnostics)
9093
}
9194
})
95+
96+
t.Run(fmt.Sprintf("ValidateParameterSet - %s", name), func(t *testing.T) {
97+
t.Parallel()
98+
request := function.SetParameterValidatorRequest{
99+
ArgumentPosition: 0,
100+
Value: test.val,
101+
}
102+
response := function.SetParameterValidatorResponse{}
103+
SizeAtMost(test.max).ValidateParameterSet(context.TODO(), request, &response)
104+
105+
if response.Error == nil && test.expectError {
106+
t.Fatal("expected error, got no error")
107+
}
108+
109+
if response.Error != nil && !test.expectError {
110+
t.Fatalf("got unexpected error: %s", response.Error)
111+
}
112+
})
92113
}
93114
}

setvalidator/size_between.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,29 @@ import (
77
"context"
88
"fmt"
99

10+
"github.com/hashicorp/terraform-plugin-framework/function"
1011
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1112

1213
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
14+
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatorfuncerr"
1315
)
1416

1517
var _ validator.Set = sizeBetweenValidator{}
18+
var _ function.SetParameterValidator = sizeBetweenValidator{}
1619

17-
// sizeBetweenValidator validates that set contains at least min elements
18-
// and at most max elements.
1920
type sizeBetweenValidator struct {
2021
min int
2122
max int
2223
}
2324

24-
// Description describes the validation in plain text formatting.
2525
func (v sizeBetweenValidator) Description(_ context.Context) string {
2626
return fmt.Sprintf("set must contain at least %d elements and at most %d elements", v.min, v.max)
2727
}
2828

29-
// MarkdownDescription describes the validation in Markdown formatting.
3029
func (v sizeBetweenValidator) MarkdownDescription(ctx context.Context) string {
3130
return v.Description(ctx)
3231
}
3332

34-
// ValidateSet performs the validation.
3533
func (v sizeBetweenValidator) ValidateSet(ctx context.Context, req validator.SetRequest, resp *validator.SetResponse) {
3634
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
3735
return
@@ -48,14 +46,30 @@ func (v sizeBetweenValidator) ValidateSet(ctx context.Context, req validator.Set
4846
}
4947
}
5048

49+
func (v sizeBetweenValidator) ValidateParameterSet(ctx context.Context, req function.SetParameterValidatorRequest, resp *function.SetParameterValidatorResponse) {
50+
if req.Value.IsNull() || req.Value.IsUnknown() {
51+
return
52+
}
53+
54+
elems := req.Value.Elements()
55+
56+
if len(elems) < v.min || len(elems) > v.max {
57+
resp.Error = validatorfuncerr.InvalidParameterValueFuncError(
58+
req.ArgumentPosition,
59+
v.Description(ctx),
60+
fmt.Sprintf("%d", len(elems)),
61+
)
62+
}
63+
}
64+
5165
// SizeBetween returns an AttributeValidator which ensures that any configured
52-
// attribute value:
66+
// attribute or function parameter value:
5367
//
5468
// - Is a Set.
5569
// - Contains at least min elements and at most max elements.
5670
//
5771
// Null (unconfigured) and unknown (known after apply) values are skipped.
58-
func SizeBetween(minVal, maxVal int) validator.Set {
72+
func SizeBetween(minVal, maxVal int) sizeBetweenValidator {
5973
return sizeBetweenValidator{
6074
min: minVal,
6175
max: maxVal,

setvalidator/size_between_example_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package setvalidator_test
66
import (
77
"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
88
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
9+
"github.com/hashicorp/terraform-plugin-framework/function"
910
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
1011
"github.com/hashicorp/terraform-plugin-framework/types"
1112
)
@@ -25,3 +26,17 @@ func ExampleSizeBetween() {
2526
},
2627
}
2728
}
29+
30+
func ExampleSizeBetween_function() {
31+
_ = function.Definition{
32+
Parameters: []function.Parameter{
33+
function.SetParameter{
34+
Name: "example_param",
35+
Validators: []function.SetParameterValidator{
36+
// Validate this set must contain at least 2 and at most 4 elements.
37+
setvalidator.SizeBetween(2, 4),
38+
},
39+
},
40+
},
41+
}
42+
}

0 commit comments

Comments
 (0)