-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathvalidator_any.go
110 lines (96 loc) · 3.38 KB
/
validator_any.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
package valgo
import (
"reflect"
)
// The Any validator's type that keeps its validator context.
type ValidatorAny struct {
context *ValidatorContext
}
// Receive a value to validate.
//
// The value can be any type;
//
// Optionally, the function can receive a name and title, in that order, to be
// displayed in the error messages. A value_%N` pattern is used as a name in the
// error messages if a name and title are not supplied; for example: value_0.
// When the name is provided but not the title, then the name is humanized to be
// used as the title as well; for example the name phone_number will be
// humanized as Phone Number.
func Any(value any, nameAndTitle ...string) *ValidatorAny {
return &ValidatorAny{context: NewContext(value, nameAndTitle...)}
}
// Return the context of the validator. The context is useful to create a custom
// validator by extending this validator.
func (validator *ValidatorAny) Context() *ValidatorContext {
return validator.context
}
// Invert the logical value associated with the next validator function.
// For example:
//
// // It will return false because `Not()` inverts the boolean value associated with the `Equal()` function
// Is(v.Any("a").Not().Equal("a")).Valid()
func (validator *ValidatorAny) Not() *ValidatorAny {
validator.context.Not()
return validator
}
// Introduces a logical OR in the chain of validation conditions, affecting the
// evaluation order and priority of subsequent validators. A value passes the
// validation if it meets any one condition following the Or() call, adhering to
// a left-to-right evaluation. This mechanism allows for validating against
// multiple criteria where satisfying any single criterion is sufficient.
// Example:
//
// // This validator will pass because the string is equals "test".
// input := "test"
// isValid := v.Is(v.String(input).MinLength(5).Or().EqualTo("test")).Valid()
func (validator *ValidatorAny) Or() *ValidatorAny {
validator.context.Or()
return validator
}
// Validate if a value is equal to another. This function internally uses
// the golang `==` operator.
// For example:
//
// status := "running"
// Is(v.Any(status).Equal("running"))
func (validator *ValidatorAny) EqualTo(value any, template ...string) *ValidatorAny {
validator.context.AddWithValue(
func() bool {
return validator.context.Value() == value
},
ErrorKeyEqualTo, value, template...)
return validator
}
// Validate if a value passes a custom function.
// For example:
//
// status := ""
// Is(v.Any(status).Passing((v any) bool {
// return v == getNewStatus()
// })
func (validator *ValidatorAny) Passing(function func(v any) bool, template ...string) *ValidatorAny {
validator.context.Add(
func() bool {
return function(validator.context.Value())
},
ErrorKeyPassing, template...)
return validator
}
// Validate if a value is nil.
// For example:
//
// var status *string
// Is(v.Any(status).Nil())
func (validator *ValidatorAny) Nil(template ...string) *ValidatorAny {
validator.context.Add(
func() bool {
val := validator.context.Value()
// In Golang nil sometimes is not equal to raw nil, such as it's explained
// here: https://dev.to/arxeiss/in-go-nil-is-not-equal-to-nil-sometimes-jn8
// So, seems using reflection is the only option here
return val == nil ||
(reflect.ValueOf(val).Kind() == reflect.Ptr && reflect.ValueOf(val).IsNil())
},
ErrorKeyNil, template...)
return validator
}