github.com/bytedance/go-tagexpr/v2@v2.9.8/validator/func.go (about) 1 package validator 2 3 import ( 4 "errors" 5 "regexp" 6 7 "github.com/nyaruka/phonenumbers" 8 9 "github.com/bytedance/go-tagexpr/v2" 10 ) 11 12 // ErrInvalidWithoutMsg verification error without error message. 13 var ErrInvalidWithoutMsg = errors.New("") 14 15 // MustRegFunc registers validator function expression. 16 // NOTE: 17 // 18 // panic if exist error; 19 // example: phone($) or phone($,'CN'); 20 // If @force=true, allow to cover the existed same @funcName; 21 // The go number types always are float64; 22 // The go string types always are string. 23 func MustRegFunc(funcName string, fn func(args ...interface{}) error, force ...bool) { 24 err := RegFunc(funcName, fn, force...) 25 if err != nil { 26 panic(err) 27 } 28 } 29 30 // RegFunc registers validator function expression. 31 // NOTE: 32 // 33 // example: phone($) or phone($,'CN'); 34 // If @force=true, allow to cover the existed same @funcName; 35 // The go number types always are float64; 36 // The go string types always are string. 37 func RegFunc(funcName string, fn func(args ...interface{}) error, force ...bool) error { 38 return tagexpr.RegFunc(funcName, func(args ...interface{}) interface{} { 39 err := fn(args...) 40 if err == nil { 41 // nil defaults to false, so returns true 42 return true 43 } 44 return err 45 }, force...) 46 } 47 48 func init() { 49 var pattern = "^([A-Za-z0-9_\\-\\.\u4e00-\u9fa5])+\\@([A-Za-z0-9_\\-\\.])+\\.([A-Za-z]{2,8})$" 50 emailRegexp := regexp.MustCompile(pattern) 51 MustRegFunc("email", func(args ...interface{}) error { 52 if len(args) != 1 { 53 return errors.New("number of parameters of email function is not one") 54 } 55 s, ok := args[0].(string) 56 if !ok { 57 return errors.New("parameter of email function is not string type") 58 } 59 matched := emailRegexp.MatchString(s) 60 if !matched { 61 // return ErrInvalidWithoutMsg 62 return errors.New("email format is incorrect") 63 } 64 return nil 65 }, true) 66 } 67 68 func init() { 69 // phone: defaultRegion is 'CN' 70 MustRegFunc("phone", func(args ...interface{}) error { 71 var numberToParse, defaultRegion string 72 var ok bool 73 switch len(args) { 74 default: 75 return errors.New("the number of parameters of phone function is not one or two") 76 case 2: 77 defaultRegion, ok = args[1].(string) 78 if !ok { 79 return errors.New("the 2nd parameter of phone function is not string type") 80 } 81 fallthrough 82 case 1: 83 numberToParse, ok = args[0].(string) 84 if !ok { 85 return errors.New("the 1st parameter of phone function is not string type") 86 } 87 } 88 if defaultRegion == "" { 89 defaultRegion = "CN" 90 } 91 num, err := phonenumbers.Parse(numberToParse, defaultRegion) 92 if err != nil { 93 return err 94 } 95 matched := phonenumbers.IsValidNumber(num) 96 if !matched { 97 // return ErrInvalidWithoutMsg 98 return errors.New("phone format is incorrect") 99 } 100 return nil 101 }, true) 102 }