validator
validator copied to clipboard
Validate type shopspring/decimal multi value
Package version eg. v8, v9:
v9
Issue, Question or Enhancement:
I'm using shopspring/decimal for decimal type.
Is there a way for me to validate multiple field in Decimal?
eg:(neg、abs) in decimal.Decimal.value, exp in decimal.Decimal
neg represents positive and negative
abs stands for all numbers
exp is the decimal point
I know RegisterCustomTypeFunc() can be use to validate a field,but how to validate multiple filed?
English is poor, forgive me.
Code sample, to showcase or reproduce:
type ProductInfo struct {
gorm.Model
Title *string `gorm:"not null" validate:"required"`
Price *decimal.Decimal `gorm:"not null;type:decimal(10,2)" validate:"required,gte=0,dive"`
Description *string `gorm:"not null;default:'';size:500" validate:"required"`
Sales *uint `gorm:"not null;default:0"`
ImgURL *string `gorm:"not null;default:''" validate:"required"`
}
// this is decimal.Decimal
type Decimal struct {
value *big.Int
exp int32
}
// big.Int
package big
type Int struct {
neg bool // sign
abs nat // absolute value of the integer
}
Try RegisterCustomTypeFunc, example - https://github.com/go-playground/validator/issues/470#issuecomment-607876264
try this example
package main
import (
"log"
"reflect"
"github.com/go-playground/validator/v10"
"github.com/shopspring/decimal"
)
// use a single instance of Validate, it caches struct info
var validate *validator.Validate
type Item struct {
Price decimal.Decimal `validate:"dgt=10"`
}
func main() {
validate = validator.New()
decimalGreaterThan()
pirce, _ := decimal.NewFromString("1")
u := Item{
Price: pirce,
}
err := validate.Struct(u)
log.Println(err)
}
func decimalGreaterThan() error {
validate.RegisterCustomTypeFunc(func(field reflect.Value) interface{} {
if valuer, ok := field.Interface().(decimal.Decimal); ok {
return valuer.String()
}
return nil
}, decimal.Decimal{})
if err := validate.RegisterValidation("dgt", func(fl validator.FieldLevel) bool {
data, ok := fl.Field().Interface().(string)
if !ok {
return false
}
value, err := decimal.NewFromString(data)
if err != nil {
return false
}
baseValue, err := decimal.NewFromString(fl.Param())
if err != nil {
return false
}
return value.GreaterThan(baseValue)
}); err != nil {
return err
}
return nil
}