-
Notifications
You must be signed in to change notification settings - Fork 3
/
validator.go
86 lines (75 loc) · 2.34 KB
/
validator.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
// gin binding validator
// Usage
// func init() {
// binding.Validator = &GinStructValidator{}
// }
package goutils
import (
"errors"
"fmt"
"reflect"
"sync"
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/validator/v10"
)
// GinStructValidator 自定义参数 binding 验证错误信息输出格式
type GinStructValidator struct {
once sync.Once
validate *validator.Validate
}
var _ binding.StructValidator = &GinStructValidator{}
// ValidatorTagName 结构体 validator 的 tag 名
var ValidatorTagName = "binding"
// ValidateStruct receives any kind of type, but only performed struct or pointer to struct type.
func (v *GinStructValidator) ValidateStruct(obj interface{}) error {
value := reflect.ValueOf(obj)
valueType := value.Kind()
if valueType == reflect.Ptr {
valueType = value.Elem().Kind()
}
if valueType == reflect.Struct {
v.lazyinit()
if errs := v.validate.Struct(obj); errs != nil {
var errmsg string
for _, e := range errs.(validator.ValidationErrors) {
errmsg += fmt.Sprintf("%s;", ValidationErrorToText(e))
}
return errors.New(errmsg)
}
}
return nil
}
// Engine returns the underlying validator engine which powers the default
// Validator instance. This is useful if you want to register custom validations
// or struct level validations. See validator GoDoc for more info -
// https://godoc.org/gopkg.in/go-playground/validator.v8
func (v *GinStructValidator) Engine() interface{} {
v.lazyinit()
return v.validate
}
func (v *GinStructValidator) lazyinit() {
v.once.Do(func() {
v.validate = validator.New()
v.validate.SetTagName(ValidatorTagName)
})
}
// ValidationErrorToText error msg for human
func ValidationErrorToText(e validator.FieldError) string {
switch e.ActualTag() {
case "required":
return fmt.Sprintf("%s is required", e.Field())
case "max":
return fmt.Sprintf("%s cannot be more than %s", e.Field(), e.Param())
case "min":
return fmt.Sprintf("%s must be more than %s", e.Field(), e.Param())
case "email":
return fmt.Sprintf("Invalid email format")
case "len":
return fmt.Sprintf("%s must be %s characters long", e.Field(), e.Param())
case "oneof":
return fmt.Sprintf("%s must be one of:[%s]", e.Field(), e.Param())
case "datetime":
return fmt.Sprintf("%s must use format as %s", e.Field(), e.Param())
}
return fmt.Sprintf("%s is not valid", e.Field())
}