forked from ebhomengo/niki
1
0
Fork 0
niki/vendor/github.com/go-ozzo/ozzo-validation/v4/minmax.go

335 lines
5.7 KiB
Go
Raw Normal View History

2024-02-18 10:42:21 +00:00
// Copyright 2016 Qiang Xue. All rights reserved.
2024-02-18 10:42:21 +00:00
// Use of this source code is governed by a MIT-style
2024-02-18 10:42:21 +00:00
// license that can be found in the LICENSE file.
package validation
import (
"fmt"
"reflect"
"time"
)
var (
2024-02-18 10:42:21 +00:00
// ErrMinGreaterEqualThanRequired is the error that returns when a value is less than a specified threshold.
2024-02-18 10:42:21 +00:00
ErrMinGreaterEqualThanRequired = NewError("validation_min_greater_equal_than_required", "must be no less than {{.threshold}}")
2024-02-18 10:42:21 +00:00
// ErrMaxLessEqualThanRequired is the error that returns when a value is greater than a specified threshold.
2024-02-18 10:42:21 +00:00
ErrMaxLessEqualThanRequired = NewError("validation_max_less_equal_than_required", "must be no greater than {{.threshold}}")
2024-02-18 10:42:21 +00:00
// ErrMinGreaterThanRequired is the error that returns when a value is less than or equal to a specified threshold.
2024-02-18 10:42:21 +00:00
ErrMinGreaterThanRequired = NewError("validation_min_greater_than_required", "must be greater than {{.threshold}}")
2024-02-18 10:42:21 +00:00
// ErrMaxLessThanRequired is the error that returns when a value is greater than or equal to a specified threshold.
2024-02-18 10:42:21 +00:00
ErrMaxLessThanRequired = NewError("validation_max_less_than_required", "must be less than {{.threshold}}")
)
// ThresholdRule is a validation rule that checks if a value satisfies the specified threshold requirement.
2024-02-18 10:42:21 +00:00
type ThresholdRule struct {
threshold interface{}
operator int
err Error
2024-02-18 10:42:21 +00:00
}
const (
greaterThan = iota
2024-02-18 10:42:21 +00:00
greaterEqualThan
2024-02-18 10:42:21 +00:00
lessThan
2024-02-18 10:42:21 +00:00
lessEqualThan
)
// Min returns a validation rule that checks if a value is greater or equal than the specified value.
2024-02-18 10:42:21 +00:00
// By calling Exclusive, the rule will check if the value is strictly greater than the specified value.
2024-02-18 10:42:21 +00:00
// Note that the value being checked and the threshold value must be of the same type.
2024-02-18 10:42:21 +00:00
// Only int, uint, float and time.Time types are supported.
2024-02-18 10:42:21 +00:00
// An empty value is considered valid. Please use the Required rule to make sure a value is not empty.
2024-02-18 10:42:21 +00:00
func Min(min interface{}) ThresholdRule {
2024-02-18 10:42:21 +00:00
return ThresholdRule{
2024-02-18 10:42:21 +00:00
threshold: min,
operator: greaterEqualThan,
err: ErrMinGreaterEqualThanRequired,
2024-02-18 10:42:21 +00:00
}
}
// Max returns a validation rule that checks if a value is less or equal than the specified value.
2024-02-18 10:42:21 +00:00
// By calling Exclusive, the rule will check if the value is strictly less than the specified value.
2024-02-18 10:42:21 +00:00
// Note that the value being checked and the threshold value must be of the same type.
2024-02-18 10:42:21 +00:00
// Only int, uint, float and time.Time types are supported.
2024-02-18 10:42:21 +00:00
// An empty value is considered valid. Please use the Required rule to make sure a value is not empty.
2024-02-18 10:42:21 +00:00
func Max(max interface{}) ThresholdRule {
2024-02-18 10:42:21 +00:00
return ThresholdRule{
2024-02-18 10:42:21 +00:00
threshold: max,
operator: lessEqualThan,
err: ErrMaxLessEqualThanRequired,
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
// Exclusive sets the comparison to exclude the boundary value.
2024-02-18 10:42:21 +00:00
func (r ThresholdRule) Exclusive() ThresholdRule {
2024-02-18 10:42:21 +00:00
if r.operator == greaterEqualThan {
2024-02-18 10:42:21 +00:00
r.operator = greaterThan
2024-02-18 10:42:21 +00:00
r.err = ErrMinGreaterThanRequired
2024-02-18 10:42:21 +00:00
} else if r.operator == lessEqualThan {
2024-02-18 10:42:21 +00:00
r.operator = lessThan
2024-02-18 10:42:21 +00:00
r.err = ErrMaxLessThanRequired
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
return r
2024-02-18 10:42:21 +00:00
}
// Validate checks if the given value is valid or not.
2024-02-18 10:42:21 +00:00
func (r ThresholdRule) Validate(value interface{}) error {
2024-02-18 10:42:21 +00:00
value, isNil := Indirect(value)
2024-02-18 10:42:21 +00:00
if isNil || IsEmpty(value) {
2024-02-18 10:42:21 +00:00
return nil
2024-02-18 10:42:21 +00:00
}
rv := reflect.ValueOf(r.threshold)
2024-02-18 10:42:21 +00:00
switch rv.Kind() {
2024-02-18 10:42:21 +00:00
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
2024-02-18 10:42:21 +00:00
v, err := ToInt(value)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
if r.compareInt(rv.Int(), v) {
2024-02-18 10:42:21 +00:00
return nil
2024-02-18 10:42:21 +00:00
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
2024-02-18 10:42:21 +00:00
v, err := ToUint(value)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
if r.compareUint(rv.Uint(), v) {
2024-02-18 10:42:21 +00:00
return nil
2024-02-18 10:42:21 +00:00
}
case reflect.Float32, reflect.Float64:
2024-02-18 10:42:21 +00:00
v, err := ToFloat(value)
2024-02-18 10:42:21 +00:00
if err != nil {
2024-02-18 10:42:21 +00:00
return err
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
if r.compareFloat(rv.Float(), v) {
2024-02-18 10:42:21 +00:00
return nil
2024-02-18 10:42:21 +00:00
}
case reflect.Struct:
2024-02-18 10:42:21 +00:00
t, ok := r.threshold.(time.Time)
2024-02-18 10:42:21 +00:00
if !ok {
2024-02-18 10:42:21 +00:00
return fmt.Errorf("type not supported: %v", rv.Type())
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
v, ok := value.(time.Time)
2024-02-18 10:42:21 +00:00
if !ok {
2024-02-18 10:42:21 +00:00
return fmt.Errorf("cannot convert %v to time.Time", reflect.TypeOf(value))
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
if v.IsZero() || r.compareTime(t, v) {
2024-02-18 10:42:21 +00:00
return nil
2024-02-18 10:42:21 +00:00
}
default:
2024-02-18 10:42:21 +00:00
return fmt.Errorf("type not supported: %v", rv.Type())
2024-02-18 10:42:21 +00:00
}
return r.err.SetParams(map[string]interface{}{"threshold": r.threshold})
2024-02-18 10:42:21 +00:00
}
// Error sets the error message for the rule.
2024-02-18 10:42:21 +00:00
func (r ThresholdRule) Error(message string) ThresholdRule {
2024-02-18 10:42:21 +00:00
r.err = r.err.SetMessage(message)
2024-02-18 10:42:21 +00:00
return r
2024-02-18 10:42:21 +00:00
}
// ErrorObject sets the error struct for the rule.
2024-02-18 10:42:21 +00:00
func (r ThresholdRule) ErrorObject(err Error) ThresholdRule {
2024-02-18 10:42:21 +00:00
r.err = err
2024-02-18 10:42:21 +00:00
return r
2024-02-18 10:42:21 +00:00
}
func (r ThresholdRule) compareInt(threshold, value int64) bool {
2024-02-18 10:42:21 +00:00
switch r.operator {
2024-02-18 10:42:21 +00:00
case greaterThan:
2024-02-18 10:42:21 +00:00
return value > threshold
2024-02-18 10:42:21 +00:00
case greaterEqualThan:
2024-02-18 10:42:21 +00:00
return value >= threshold
2024-02-18 10:42:21 +00:00
case lessThan:
2024-02-18 10:42:21 +00:00
return value < threshold
2024-02-18 10:42:21 +00:00
default:
2024-02-18 10:42:21 +00:00
return value <= threshold
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
func (r ThresholdRule) compareUint(threshold, value uint64) bool {
2024-02-18 10:42:21 +00:00
switch r.operator {
2024-02-18 10:42:21 +00:00
case greaterThan:
2024-02-18 10:42:21 +00:00
return value > threshold
2024-02-18 10:42:21 +00:00
case greaterEqualThan:
2024-02-18 10:42:21 +00:00
return value >= threshold
2024-02-18 10:42:21 +00:00
case lessThan:
2024-02-18 10:42:21 +00:00
return value < threshold
2024-02-18 10:42:21 +00:00
default:
2024-02-18 10:42:21 +00:00
return value <= threshold
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
func (r ThresholdRule) compareFloat(threshold, value float64) bool {
2024-02-18 10:42:21 +00:00
switch r.operator {
2024-02-18 10:42:21 +00:00
case greaterThan:
2024-02-18 10:42:21 +00:00
return value > threshold
2024-02-18 10:42:21 +00:00
case greaterEqualThan:
2024-02-18 10:42:21 +00:00
return value >= threshold
2024-02-18 10:42:21 +00:00
case lessThan:
2024-02-18 10:42:21 +00:00
return value < threshold
2024-02-18 10:42:21 +00:00
default:
2024-02-18 10:42:21 +00:00
return value <= threshold
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}
func (r ThresholdRule) compareTime(threshold, value time.Time) bool {
2024-02-18 10:42:21 +00:00
switch r.operator {
2024-02-18 10:42:21 +00:00
case greaterThan:
2024-02-18 10:42:21 +00:00
return value.After(threshold)
2024-02-18 10:42:21 +00:00
case greaterEqualThan:
2024-02-18 10:42:21 +00:00
return value.After(threshold) || value.Equal(threshold)
2024-02-18 10:42:21 +00:00
case lessThan:
2024-02-18 10:42:21 +00:00
return value.Before(threshold)
2024-02-18 10:42:21 +00:00
default:
2024-02-18 10:42:21 +00:00
return value.Before(threshold) || value.Equal(threshold)
2024-02-18 10:42:21 +00:00
}
2024-02-18 10:42:21 +00:00
}