1
|
|
|
package validation_test |
2
|
|
|
|
3
|
|
|
import ( |
4
|
|
|
"context" |
5
|
|
|
"errors" |
6
|
|
|
"fmt" |
7
|
|
|
"regexp" |
8
|
|
|
|
9
|
|
|
"github.com/muonsoft/validation" |
10
|
|
|
"github.com/muonsoft/validation/it" |
11
|
|
|
"github.com/muonsoft/validation/validator" |
12
|
|
|
) |
13
|
|
|
|
14
|
|
|
var ErrNotNumeric = errors.New("not numeric") |
15
|
|
|
|
16
|
|
|
type NumericConstraint struct { |
17
|
|
|
matcher *regexp.Regexp |
18
|
|
|
} |
19
|
|
|
|
20
|
|
|
// it is recommended to use semantic constructors for constraints. |
21
|
|
|
func IsNumeric() NumericConstraint { |
22
|
|
|
return NumericConstraint{matcher: regexp.MustCompile("^[0-9]+$")} |
23
|
|
|
} |
24
|
|
|
|
25
|
|
|
func (c NumericConstraint) ValidateString(ctx context.Context, validator *validation.Validator, value *string) error { |
26
|
|
|
// usually, you should ignore empty values |
27
|
|
|
// to check for an empty value you should use it.NotBlankConstraint |
28
|
|
|
if value == nil || *value == "" { |
29
|
|
|
return nil |
30
|
|
|
} |
31
|
|
|
|
32
|
|
|
if c.matcher.MatchString(*value) { |
33
|
|
|
return nil |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
// use the validator to build violation with translations |
37
|
|
|
return validator.CreateViolation(ctx, ErrNotNumeric, "This value should be numeric.") |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
func ExampleValidator_Validate_customConstraint() { |
41
|
|
|
s := "alpha" |
42
|
|
|
|
43
|
|
|
err := validator.Validate( |
44
|
|
|
context.Background(), |
45
|
|
|
validation.String(s, it.IsNotBlank(), IsNumeric()), |
46
|
|
|
) |
47
|
|
|
|
48
|
|
|
fmt.Println(err) |
49
|
|
|
fmt.Println("errors.Is(err, ErrNotNumeric) =", errors.Is(err, ErrNotNumeric)) |
50
|
|
|
// Output: |
51
|
|
|
// violation: "This value should be numeric." |
52
|
|
|
// errors.Is(err, ErrNotNumeric) = true |
53
|
|
|
} |
54
|
|
|
|