-
Notifications
You must be signed in to change notification settings - Fork 3
/
numbers.go
83 lines (72 loc) · 2.48 KB
/
numbers.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
package goval
import (
"context"
"github.com/pkg-id/goval/constraints"
"github.com/pkg-id/goval/funcs"
)
// NumberConstraint is set types that treats as numbers.
type NumberConstraint interface {
constraints.Integer | constraints.Float
}
// NumberValidator is a validator that validates numbers.
type NumberValidator[T NumberConstraint] FunctionValidator[T]
// Number returns a NumberValidator with no rules.
func Number[T NumberConstraint]() NumberValidator[T] {
return NopFunctionValidator[T]
}
// Validate executes the validation rules immediately.
func (f NumberValidator[T]) Validate(ctx context.Context, value T) error {
return validatorOf(f, value).Validate(ctx)
}
// With attaches the next rule to the chain.
func (f NumberValidator[T]) With(next NumberValidator[T]) NumberValidator[T] {
return Chain(f, next)
}
// Required ensures the number is not zero.
func (f NumberValidator[T]) Required() NumberValidator[T] {
return f.With(func(ctx context.Context, value T) error {
var zero T
if value == zero {
return NewRuleError(NumberRequired)
}
return nil
})
}
// Min ensures the number is not less than the given min.
func (f NumberValidator[T]) Min(min T) NumberValidator[T] {
return f.With(func(ctx context.Context, value T) error {
if value < min {
return NewRuleError(NumberMin, min)
}
return nil
})
}
// Max ensures the number is not greater than the given max.
func (f NumberValidator[T]) Max(max T) NumberValidator[T] {
return f.With(func(ctx context.Context, value T) error {
if value > max {
return NewRuleError(NumberMax, max)
}
return nil
})
}
// In ensures that the provided number is one of the specified options.
func (f NumberValidator[T]) In(options ...T) NumberValidator[T] {
return f.With(func(ctx context.Context, value T) error {
ok := funcs.Contains(options, func(opt T) bool { return opt == value })
if !ok {
return NewRuleError(NumberIn, options)
}
return nil
})
}
// When adds validation logic to the chain based on a condition for numeric values of type T.
//
// 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 NumberValidator[T] instance and returns a new NumberValidator[T] instance with
// additional validation logic.
func (f NumberValidator[T]) When(p Predicate[T], m Mapper[T, NumberValidator[T]]) NumberValidator[T] {
return whenLinker(f, p, m)
}