-
Notifications
You must be signed in to change notification settings - Fork 3
/
string.go
121 lines (104 loc) · 3.37 KB
/
string.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package goval
import (
"context"
"fmt"
"strings"
"github.com/pkg-id/goval/funcs"
)
// StringValidator is a FunctionValidator that validates string.
// For backward compatibility.
type StringValidator = SVV[string]
// String returns a StringValidator with no rules.
// For backward compatibility.
func String() StringValidator {
return StringVariant[string]()
}
// SVV (String Variant Validator) is a FunctionValidator that validates string
// variants.
type SVV[T ~string] FunctionValidator[T]
// StringVariant returns a SVV with no rules.
func StringVariant[T ~string]() SVV[T] {
return NopFunctionValidator[T]
}
// Validate executes the validation rules immediately.
func (f SVV[T]) Validate(ctx context.Context, value T) error {
return validatorOf(f, value).Validate(ctx)
}
// With attaches the next rule to the chain.
func (f SVV[T]) With(next SVV[T]) SVV[T] {
return Chain(f, next)
}
// Required ensures the string is not empty.
func (f SVV[T]) Required() SVV[T] {
return f.With(func(ctx context.Context, value T) error {
if value == "" {
return NewRuleError(StringRequired)
}
return nil
})
}
// Min ensures the length of the string is not less than the given length.
func (f SVV[T]) Min(length int) SVV[T] {
return f.With(func(ctx context.Context, value T) error {
if len(value) < length {
return NewRuleError(StringMin, length)
}
return nil
})
}
// Max ensures the length of the string is not greater than the given length.
func (f SVV[T]) Max(length int) SVV[T] {
return f.With(func(ctx context.Context, value T) error {
if len(value) > length {
return NewRuleError(StringMax, length)
}
return nil
})
}
// Match ensures the string matches the given pattern.
// If pattern cause panic, will be recovered.
func (f SVV[T]) Match(pattern Pattern) SVV[T] {
return f.With(func(ctx context.Context, value T) (err error) {
defer func() {
if rec := recover(); rec != nil {
err = fmt.Errorf("panic: %v", rec)
}
}()
exp := pattern.RegExp()
if !exp.MatchString(string(value)) {
return NewRuleError(StringMatch, exp.String())
}
return err
})
}
// In ensures that the provided string is one of the specified options.
// This validation is case-sensitive, use InFold to perform a case-insensitive In validation.
func (f SVV[T]) In(options ...T) SVV[T] {
return f.With(func(ctx context.Context, value T) error {
ok := funcs.Contains(options, func(opt T) bool { return value == opt })
if !ok {
return NewRuleError(StringIn, options)
}
return nil
})
}
// InFold ensures that the provided string is one of the specified options with case-insensitivity.
func (f SVV[T]) InFold(options ...T) SVV[T] {
return f.With(func(ctx context.Context, value T) error {
ok := funcs.Contains(options, func(opt T) bool { return strings.EqualFold(string(value), string(opt)) })
if !ok {
return NewRuleError(StringInFold, options)
}
return nil
})
}
// When adds validation logic to the chain based on a condition for string values.
//
// If the predicate returns true, the result of the mapper function is added to the chain,
// and the input value is validated using the new chain. Otherwise, the original chain is returned unmodified.
//
// The mapper function takes a StringValidator instance and returns a new StringValidator instance with
// additional validation logic.
func (f SVV[T]) When(p Predicate[T], m Mapper[T, SVV[T]]) SVV[T] {
return whenLinker(f, p, m)
}