validation: support required option for some struct tag valids

This commit is contained in:
miraclesu 2017-07-03 16:14:29 +08:00
parent 82586c70e9
commit e72b02b7cc
4 changed files with 81 additions and 0 deletions

View File

@ -64,6 +64,9 @@ Struct Tag Use:
func main() {
valid := validation.Validation{}
// ignore empty field valid
// see CanSkipFuncs
// valid := validation.Validation{RequiredFirst:true}
u := user{Name: "test", Age: 40}
b, err := valid.Valid(u)
if err != nil {

View File

@ -106,6 +106,11 @@ func (r *Result) Message(message string, args ...interface{}) *Result {
// A Validation context manages data validation and error messages.
type Validation struct {
// if this field set true, in struct tag valid
// if the struct field vale is empty
// it will skip those valid functions, see CanSkipFuncs
RequiredFirst bool
Errors []*Error
ErrorsMap map[string]*Error
}
@ -324,7 +329,19 @@ func (v *Validation) Valid(obj interface{}) (b bool, err error) {
if vfs, err = getValidFuncs(objT.Field(i)); err != nil {
return
}
var hasReuired bool
for _, vf := range vfs {
if vf.Name == "Required" {
hasReuired = true
}
if !hasReuired && v.RequiredFirst && len(objV.Field(i).String()) == 0 {
if _, ok := CanSkipFuncs[vf.Name]; ok {
continue
}
}
if _, err = funcs.Call(vf.Name,
mergeParam(v, objV.Field(i).Interface(), vf.Params)...); err != nil {
return

View File

@ -391,3 +391,54 @@ func TestRecursiveValid(t *testing.T) {
t.Error("validation should not be passed")
}
}
func TestSkipValid(t *testing.T) {
type User struct {
ID int
Email string `valid:"Email"`
ReqEmail string `valid:"Required;Email"`
IP string `valid:"IP"`
ReqIP string `valid:"Required;IP"`
Mobile string `valid:"Mobile"`
ReqMobile string `valid:"Required;Mobile"`
Tel string `valid:"Tel"`
ReqTel string `valid:"Required;Tel"`
Phone string `valid:"Phone"`
ReqPhone string `valid:"Required;Phone"`
ZipCode string `valid:"ZipCode"`
ReqZipCode string `valid:"Required;ZipCode"`
}
u := User{
ReqEmail: "a@a.com",
ReqIP: "127.0.0.1",
ReqMobile: "18888888888",
ReqTel: "02088888888",
ReqPhone: "02088888888",
ReqZipCode: "510000",
}
valid := Validation{}
b, err := valid.Valid(u)
if err != nil {
t.Fatal(err)
}
if b {
t.Fatal("validation should not be passed")
}
valid = Validation{RequiredFirst: true}
b, err = valid.Valid(u)
if err != nil {
t.Fatal(err)
}
if !b {
t.Fatal("validation should be passed")
}
}

View File

@ -23,6 +23,16 @@ import (
"unicode/utf8"
)
// CanSkipFuncs will skip valid if RequiredFirst is true and the struct field's value is empty
var CanSkipFuncs = map[string]struct{}{
"Email": struct{}{},
"IP": struct{}{},
"Mobile": struct{}{},
"Tel": struct{}{},
"Phone": struct{}{},
"ZipCode": struct{}{},
}
// MessageTmpls store commond validate template
var MessageTmpls = map[string]string{
"Required": "Can not be empty",