From d82475935d4346f3576305994fe296e0d935cca0 Mon Sep 17 00:00:00 2001 From: HaoYu Zhang <310123665@qq.com> Date: Thu, 22 Aug 2024 21:32:16 +0800 Subject: [PATCH] add Enum string to validators (#5697) * feature: add Enum string to validators * feature: add information for Enum errors --- core/validation/README.md | 1 + core/validation/validation.go | 5 +++++ core/validation/validation_test.go | 16 ++++++++++++++ core/validation/validators.go | 35 ++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/core/validation/README.md b/core/validation/README.md index dee5a7b1..0f9c1677 100644 --- a/core/validation/README.md +++ b/core/validation/README.md @@ -140,6 +140,7 @@ Struct Tag Functions: Tel Phone ZipCode + Enum ## LICENSE diff --git a/core/validation/validation.go b/core/validation/validation.go index c7527334..bfb1dd92 100644 --- a/core/validation/validation.go +++ b/core/validation/validation.go @@ -245,6 +245,11 @@ func (v *Validation) ZipCode(obj interface{}, key string) *Result { return v.apply(ZipCode{Match{Regexp: zipCodePattern}, key}, obj) } +// Enum Test that the obj is in the specified enumeration if type is string +func (v *Validation) Enum(obj interface{}, vals string, key string) *Result { + return v.apply(Enum{vals, key}, obj) +} + func (v *Validation) apply(chk Validator, obj interface{}) *Result { if nil == obj { if chk.IsSatisfied(obj) { diff --git a/core/validation/validation_test.go b/core/validation/validation_test.go index 00a45a98..eaa82bd2 100644 --- a/core/validation/validation_test.go +++ b/core/validation/validation_test.go @@ -360,6 +360,22 @@ func TestZipCode(t *testing.T) { } } +func TestEnum(t *testing.T) { + valid := Validation{} + + if valid.Enum("sms_code", "sms|email|code", "enum").Ok { + t.Error("\"sms_code\" is in the enum list of \"sms|email|code\" should be false") + } + + if !valid.Enum("sms", "email|sms|code", "enum").Ok { + t.Error("\"sms\" is in the enum list of \"email|sms|code\" should be true") + } + + if valid.Enum(200, "code|email|sms", "enum").Ok { + t.Error("200 is in the enum list of \"code|email|sms\" should be false") + } +} + func TestValid(t *testing.T) { type user struct { ID int diff --git a/core/validation/validators.go b/core/validation/validators.go index 3150fda5..366b9eec 100644 --- a/core/validation/validators.go +++ b/core/validation/validators.go @@ -58,6 +58,7 @@ var MessageTmpls = map[string]string{ "Tel": "Must be valid telephone number", "Phone": "Must be valid telephone or mobile phone number", "ZipCode": "Must be valid zipcode", + "Enum": "Must be a string value in \"%s\"", } var once sync.Once @@ -738,3 +739,37 @@ func (z ZipCode) GetKey() string { func (z ZipCode) GetLimitValue() interface{} { return nil } + +// Enum Requires that the field must be within the enumerated value +type Enum struct { + Rules string + Key string +} + +// IsSatisfied judge whether obj is valid +func (e Enum) IsSatisfied(i interface{}) bool { + if val, ok := i.(string); ok { + roles := strings.Split(e.Rules, "|") + for _, v := range roles { + if val == strings.TrimSpace(v) { + return true + } + } + } + return false +} + +// DefaultMessage return the default Enum error message +func (e Enum) DefaultMessage() string { + return fmt.Sprintf(MessageTmpls["Enum"], e.Rules) +} + +// GetKey return the e.Key +func (e Enum) GetKey() string { + return e.Key +} + +// GetLimitValue return nil now +func (Enum) GetLimitValue() interface{} { + return nil +}