1
|
|
|
package validation |
2
|
|
|
|
3
|
|
|
import ( |
4
|
|
|
"errors" |
5
|
|
|
"fmt" |
6
|
|
|
"strings" |
7
|
|
|
|
8
|
|
|
"github.com/muonsoft/validation/message" |
9
|
|
|
) |
10
|
|
|
|
11
|
|
|
var ( |
12
|
|
|
ErrInvalidDate = NewError("invalid date", message.InvalidDate) |
13
|
|
|
ErrInvalidDateTime = NewError("invalid datetime", message.InvalidDateTime) |
14
|
|
|
ErrInvalidEAN13 = NewError("invalid EAN-13", message.InvalidEAN13) |
15
|
|
|
ErrInvalidEAN8 = NewError("invalid EAN-8", message.InvalidEAN8) |
16
|
|
|
ErrInvalidEmail = NewError("invalid email", message.InvalidEmail) |
17
|
|
|
ErrInvalidHostname = NewError("invalid hostname", message.InvalidHostname) |
18
|
|
|
ErrInvalidIP = NewError("invalid IP address", message.InvalidIP) |
19
|
|
|
ErrInvalidJSON = NewError("invalid JSON", message.InvalidJSON) |
20
|
|
|
ErrInvalidTime = NewError("invalid time", message.InvalidTime) |
21
|
|
|
ErrInvalidULID = NewError("invalid ULID", message.InvalidULID) |
22
|
1 |
|
ErrInvalidUPCA = NewError("invalid UPC-A", message.InvalidUPCA) |
23
|
|
|
ErrInvalidUPCE = NewError("invalid UPC-E", message.InvalidUPCE) |
24
|
|
|
ErrInvalidURL = NewError("invalid URL", message.InvalidURL) |
25
|
|
|
ErrInvalidUUID = NewError("invalid UUID", message.InvalidUUID) |
26
|
|
|
ErrIsBlank = NewError("is blank", message.IsBlank) |
27
|
|
|
ErrIsEqual = NewError("is equal", message.IsEqual) |
28
|
|
|
ErrIsNil = NewError("is nil", message.IsNil) |
29
|
|
|
ErrNoSuchChoice = NewError("no such choice", message.NoSuchChoice) |
30
|
|
|
ErrNotBlank = NewError("is not blank", message.NotBlank) |
31
|
|
|
ErrNotDivisible = NewError("is not divisible", message.NotDivisible) |
32
|
|
|
ErrNotDivisibleCount = NewError("not divisible count", message.NotDivisibleCount) |
33
|
|
|
ErrNotEqual = NewError("is not equal", message.NotEqual) |
34
|
|
|
ErrNotExactCount = NewError("not exact count", message.NotExactCount) |
35
|
1 |
|
ErrNotExactLength = NewError("not exact length", message.NotExactLength) |
36
|
|
|
ErrNotFalse = NewError("is not false", message.NotFalse) |
37
|
|
|
ErrNotInRange = NewError("is not in range", message.NotInRange) |
38
|
|
|
ErrNotInteger = NewError("is not an integer", message.NotInteger) |
39
|
|
|
ErrNotNegative = NewError("is not negative", message.NotNegative) |
40
|
|
|
ErrNotNegativeOrZero = NewError("is not negative or zero", message.NotNegativeOrZero) |
41
|
|
|
ErrNotNil = NewError("is not nil", message.NotNil) |
42
|
|
|
ErrNotNumeric = NewError("is not numeric", message.NotNumeric) |
43
|
|
|
ErrNotPositive = NewError("is not positive", message.NotPositive) |
44
|
|
|
ErrNotPositiveOrZero = NewError("is not positive or zero", message.NotPositiveOrZero) |
45
|
1 |
|
ErrNotTrue = NewError("is not true", message.NotTrue) |
46
|
|
|
ErrNotUnique = NewError("is not unique", message.NotUnique) |
47
|
|
|
ErrNotValid = NewError("is not valid", message.NotValid) |
48
|
|
|
ErrProhibitedIP = NewError("is prohibited IP", message.ProhibitedIP) |
49
|
|
|
ErrProhibitedURL = NewError("is prohibited URL", message.ProhibitedURL) |
50
|
|
|
ErrTooEarly = NewError("is too early", message.TooEarly) |
51
|
|
|
ErrTooEarlyOrEqual = NewError("is too early or equal", message.TooEarlyOrEqual) |
52
|
|
|
ErrTooFewElements = NewError("too few elements", message.TooFewElements) |
53
|
|
|
ErrTooHigh = NewError("is too high", message.TooHigh) |
54
|
|
|
ErrTooHighOrEqual = NewError("is too high or equal", message.TooHighOrEqual) |
55
|
1 |
|
ErrTooLate = NewError("is too late", message.TooLate) |
56
|
|
|
ErrTooLateOrEqual = NewError("is too late or equal", message.TooLateOrEqual) |
57
|
|
|
ErrTooLong = NewError("is too long", message.TooLong) |
58
|
|
|
ErrTooLow = NewError("is too low", message.TooLow) |
59
|
|
|
ErrTooLowOrEqual = NewError("is too low or equal", message.TooLowOrEqual) |
60
|
|
|
ErrTooManyElements = NewError("too many elements", message.TooManyElements) |
61
|
|
|
ErrTooShort = NewError("is too short", message.TooShort) |
62
|
|
|
) |
63
|
|
|
|
64
|
|
|
// Error is a base type for static validation error used as an underlying error for [Violation]. |
65
|
|
|
// It can be used to programmatically test for a specific violation. |
66
|
|
|
// Error code values are protected by backward compatibility rules, message values are not protected. |
67
|
|
|
type Error struct { |
68
|
|
|
code string |
69
|
|
|
message string |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
// NewError creates a static validation error. It should be used to create only package-level errors. |
73
|
|
|
func NewError(code string, message string) *Error { |
74
|
|
|
return &Error{code: code, message: message} |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
// Error returns error code. This code is protected by backward compatibility rules. |
78
|
|
|
func (err *Error) Error() string { return err.code } |
79
|
|
|
|
80
|
|
|
// Message returns message template that will be shown to the end user. |
81
|
|
|
// Be aware. This message is not protected by backward compatibility rules and may be changed even in patch versions. |
82
|
|
|
func (err *Error) Message() string { return err.message } |
83
|
|
|
|
84
|
|
|
// ConstraintError is used to return critical error from constraint that immediately |
85
|
|
|
// stops the validation process. It is recommended to use [Validator.CreateConstraintError] method |
86
|
|
|
// to initiate an error from current validation context. |
87
|
|
|
type ConstraintError struct { |
88
|
|
|
ConstraintName string |
89
|
|
|
Path *PropertyPath |
90
|
|
|
Description string |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
func (err *ConstraintError) Error() string { |
94
|
|
|
var s strings.Builder |
95
|
|
|
s.WriteString("validate by " + err.ConstraintName) |
96
|
|
|
if err.Path != nil { |
97
|
|
|
s.WriteString(` at path "` + err.Path.String() + `"`) |
98
|
|
|
} |
99
|
|
|
s.WriteString(": " + err.Description) |
100
|
|
|
|
101
|
|
|
return s.String() |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
// ConstraintNotFoundError is returned when trying to get a constraint |
105
|
|
|
// from the validator store using a non-existent key. |
106
|
|
|
type ConstraintNotFoundError struct { |
107
|
|
|
Key string |
108
|
|
|
Type string |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
func (err *ConstraintNotFoundError) Error() string { |
112
|
|
|
return fmt.Sprintf(`constraint by key "%s" of type "%s" is not found`, err.Key, err.Type) |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
var errTranslatorOptionsDenied = errors.New("translation options denied when using custom translator") |
116
|
|
|
|