Compare commits

..

13 Commits

11 changed files with 569 additions and 22 deletions

24
go.mod
View File

@ -3,27 +3,43 @@ module git.zhangdeman.cn/gateway/validator
go 1.22.2
require (
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241125065114-f919222003d9
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241108082010-42ae8fe5ebdc
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250122075709-5ecf3edb4a00
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20241125062526-91423fb146e0
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250124091620-c757e551a8c9
github.com/go-playground/validator/v10 v10.24.0
github.com/smartystreets/goconvey v1.8.1
github.com/stretchr/testify v1.9.0
github.com/tidwall/gjson v1.18.0
github.com/tidwall/sjson v1.2.5
)
require (
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 // indirect
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect
github.com/BurntSushi/toml v1.4.0 // indirect
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/gopherjs/gopherjs v1.17.2 // indirect
github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mozillazg/go-pinyin v0.20.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/smarty/assertions v1.15.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
golang.org/x/crypto v0.32.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace git.zhangdeman.cn/zhangdeman/consts => ../consts
replace git.zhangdeman.cn/zhangdeman/wrapper => ../wrapper

48
go.sum
View File

@ -1,33 +1,33 @@
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241023090605-10cff9173059 h1:TPAYdTKKUjgxtCnK38d1Tb4teyQp1C7wYHPdR32yZtM=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241023090605-10cff9173059/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241125061350-1f5050978fc3 h1:/40XIygeSxRhPQc3/7pKGpV5hg8jwrMwh1+YiyCHdNI=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241125061350-1f5050978fc3/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241125065114-f919222003d9 h1:TP/M3WnGsxh0Vr6YuS1i28hw1oV//YbdCoI46PUBIA0=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241125065114-f919222003d9/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241024134352-ce2d84d282ba h1:hgajrPZGoDY9P+x6iqcS06pnu5t+N7DOfpmRwb+TZ4s=
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241024134352-ce2d84d282ba/go.mod h1:V4Dfg1v/JVIZGEKCm6/aehs8hK+Xow1dkL1yiQymXlQ=
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 h1:s6d4b6yY+NaK1AzoBD1pxqsuygEHQz0Oie86c45geDw=
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4/go.mod h1:V4Dfg1v/JVIZGEKCm6/aehs8hK+Xow1dkL1yiQymXlQ=
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQMuJ4xNfP2Abl1Msmpa3fASLWYkNlqDFF/6GN0Y=
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI=
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241023104258-2e0a298aa558 h1:ZVJyyDKfYeA3TsN8UOi4IprkouK4wIIfCKe+F9byLWA=
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241023104258-2e0a298aa558/go.mod h1:/9eicss/Dt9tp2jwZ/4cXDqDKo/Dez+HuT5/NGdqW+s=
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241108082010-42ae8fe5ebdc h1:jtdEMr/xNchJDEoCnvMr4JXT9+biYQu625Cj+dz025w=
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241108082010-42ae8fe5ebdc/go.mod h1:XqgER4jDYwskFgj2riJ9XptIjzgYWubY+Zq8iB2WkY0=
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd h1:q7GG14qgXKB4MEXQFOe7/UYebsqMfPaSX80TcPdOosI=
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs=
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI=
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20241024135251-6dd5f7ac6254 h1:20NfKC/5EwTpSLodvXCPM2CmKWuDgggratYB2r9ihLM=
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20241024135251-6dd5f7ac6254/go.mod h1:7D7XZqEMCHSTnmDM4t3xWcrpJn1TC2EyDLd9ScP5gN4=
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20241125062526-91423fb146e0 h1:aGQADmQKTF7c8+s3acnn569sTJwjlLhhhZfQ6f4nAH0=
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20241125062526-91423fb146e0/go.mod h1:lvVOIrYDvCQHUzBdaOwKSrxT9ubcXQJBsafWMWu+I14=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg=
github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
@ -36,6 +36,10 @@ github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+
github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
@ -50,6 +54,14 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@ -0,0 +1,35 @@
// Package abstract ...
//
// Description : abstract ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-01-23 18:44
package abstract
import (
"git.zhangdeman.cn/gateway/validator/v10/define"
)
// IValidateRuleGenerateFunc 生成校验规则的方法约束
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 18:46 2025/1/23
//
// 参数说明
//
// - validateRule: 参数验证规则, 具体参见静态库声明
// - paramList: 验证规则需要的参数列表, 可以为空
//
// 返回值说明
// - express: 生成的表达式
// - err: 表达式生成过程中出现的异常
type IValidateRuleGenerateFunc func(ruleConfig define.GenerateRuleExpressConfig) (express string, err error)
// IFieldValidateRuleGenerateFunc 字段验证规则生成方法
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:16 2025/1/24
type IFieldValidateRuleGenerateFunc func(fieldValidateRule define.FieldValidateGenerateConfig) (express string, err error)

82
v10/default.go Normal file
View File

@ -0,0 +1,82 @@
// Package v10 ...
//
// Description : v10 ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-01-24 10:32
package v10
import (
"errors"
"fmt"
"git.zhangdeman.cn/gateway/validator/v10/define"
"strings"
)
// DefaultValidateRuleGenerateFunc 验证规则生成的默认方法
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:33 2025/1/24
func DefaultValidateRuleGenerateFunc(validateRule define.GenerateRuleExpressConfig) (express string, err error) {
ruleConfig := validateRule.Rule.Config()
if len(ruleConfig.ValidatorRule.String()) == 0 {
return "", define.ErrValidatorRuleIsEmpty
}
if ruleConfig.WithoutParam {
// 验证规则不需要任何参数, 舍弃参数
return ruleConfig.ValidatorRule.String(), nil
}
// 验证参数数量
if ruleConfig.MinParamCnt > 0 && len(validateRule.ParamList) < ruleConfig.MinParamCnt {
return "", errors.New(ruleConfig.ValidatorRule.String() + " : " + define.ErrValidatorRuleParamCntIsTooLess.Error() + "-> " + fmt.Sprintf("%v", ruleConfig.MinParamCnt))
}
if ruleConfig.MaxParamCnt > 0 && len(validateRule.ParamList) > ruleConfig.MaxParamCnt {
return "", errors.New(ruleConfig.ValidatorRule.String() + " :" + define.ErrValidatorRuleParamCntIsTooMore.Error() + " -> " + fmt.Sprintf("%v", ruleConfig.MaxParamCnt))
}
if ruleConfig.ParamCntMustEven && len(validateRule.ParamList)%2 != 0 {
return "", errors.New(ruleConfig.ValidatorRule.String() + " : " + define.ErrValidatorRuleParamCntIsNotEven.Error())
}
paramStrList := make([]string, 0)
for _, param := range validateRule.ParamList {
paramStrList = append(paramStrList, fmt.Sprintf("%v", param))
}
return ruleConfig.ValidatorRule.String() + "=" + strings.Join(paramStrList, " "), nil
}
// DefaultFieldValidateRuleGenerateFunc 字段验证表达式生成
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:44 2025/1/24
func DefaultFieldValidateRuleGenerateFunc(fieldValidateRule define.FieldValidateGenerateConfig) (string, error) {
fieldValidateRule.Field = strings.TrimSpace(fieldValidateRule.Field)
if len(fieldValidateRule.Field) == 0 {
return "", define.ErrValidatorRuleFieldIsEmpty
}
if len(fieldValidateRule.RuleGroup) == 0 && len(fieldValidateRule.RuleSimple.Rule.String()) == 0 {
return "", define.ErrValidatorRuleGroupOrSimpleRuleAllEmpty
}
if len(fieldValidateRule.RuleGroup) == 0 {
// note: 当 fieldValidateRule.RuleGroup 不为空时, 会忽略 fieldValidateRule.RuleSimple 配置
fieldValidateRule.RuleGroup = [][]define.GenerateRuleExpressConfig{
[]define.GenerateRuleExpressConfig{
fieldValidateRule.RuleSimple,
},
}
}
finalExpressList := make([]string, 0)
for _, itemGroupList := range fieldValidateRule.RuleGroup {
expressList := make([]string, 0)
for _, itemRule := range itemGroupList {
if fieldExpress, err := validatorRuleExpressGenerateFunc(itemRule); nil != err {
return "", err
} else {
expressList = append(expressList, fieldExpress)
}
}
finalExpressList = append(finalExpressList, strings.Join(expressList, ","))
}
return strings.Join(finalExpressList, "|"), nil
}

132
v10/default_test.go Normal file
View File

@ -0,0 +1,132 @@
// Package v10 ...
//
// Description : v10 ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-01-24 12:01
package v10
import (
"git.zhangdeman.cn/gateway/validator/v10/define"
"git.zhangdeman.cn/zhangdeman/consts"
. "github.com/smartystreets/goconvey/convey"
"strings"
"testing"
)
// TestDefaultValidateRuleGenerateFunc 表达式生成函数测试
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 12:02 2025/1/24
func TestDefaultValidateRuleGenerateFunc(t *testing.T) {
Convey("传入的验证规则未注册", t, func() {
testRule := consts.ValidatorRule("invalid_rule")
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
Rule: testRule,
ParamList: nil,
})
So(err, ShouldBeError)
So(define.IsErr(err, define.ErrValidatorRuleIsEmpty.Error()), ShouldBeTrue)
So(res, ShouldBeEmpty)
})
Convey("传入规则无参数", t, func() {
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
Rule: consts.ValidatorRuleCommonRequired,
ParamList: nil,
})
So(err, ShouldBeNil)
So(res, ShouldEqual, consts.ValidatorRuleCommonRequired.String())
})
Convey("传入oneof枚举值缺少枚举值列表", t, func() {
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
Rule: consts.ValidatorRuleCommonOneOf,
ParamList: nil,
})
So(err, ShouldBeError)
So(define.IsErr(err, define.ErrValidatorRuleParamCntIsTooLess.Error()), ShouldBeTrue)
So(res, ShouldEqual, "")
})
Convey("传入oneof枚举值构建成功", t, func() {
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
Rule: consts.ValidatorRuleCommonOneOf,
ParamList: []any{"name", "1", 2, 3},
})
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
So(res, ShouldEqual, consts.ValidatorRuleCommonOneOf.String()+"=name 1 2 3")
})
Convey("传入RequiredIf枚举值 -> 参数少于2", t, func() {
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
Rule: consts.ValidatorRuleCommonRequiredIf,
ParamList: []any{},
})
So(err, ShouldNotBeNil)
So(define.IsErr(err, define.ErrValidatorRuleParamCntIsTooLess.Error()), ShouldBeTrue)
So(res, ShouldBeEmpty)
})
Convey("传入RequiredIf枚举值 -> 参数奇数个", t, func() {
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
Rule: consts.ValidatorRuleCommonRequiredIf,
ParamList: []any{1, 2, 3},
})
So(err, ShouldNotBeNil)
So(define.IsErr(err, define.ErrValidatorRuleParamCntIsNotEven.Error()), ShouldBeTrue)
So(res, ShouldBeEmpty)
})
Convey("传入RequiredIf枚举值 -> 构建成功", t, func() {
res, err := DefaultValidateRuleGenerateFunc(define.GenerateRuleExpressConfig{
Rule: consts.ValidatorRuleCommonRequiredIf,
ParamList: []any{1, 2, 3, 4},
})
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
So(res, ShouldEqual, consts.ValidatorRuleCommonRequiredIf.String()+"=1 2 3 4")
})
}
// TestDefaultFieldValidateRuleGenerateFunc 测试字段验证规则生成逻辑
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:53 2025/1/24
func TestDefaultFieldValidateRuleGenerateFunc(t *testing.T) {
Convey("未传入待验证字段", t, func() {
res, err := DefaultFieldValidateRuleGenerateFunc(define.FieldValidateGenerateConfig{
Field: "",
})
So(err, ShouldNotBeNil)
So(define.IsErr(err, define.ErrValidatorRuleFieldIsEmpty.Error()), ShouldBeTrue)
So(res, ShouldBeEmpty)
})
Convey("传入待验证字段有空格组成", t, func() {
res, err := DefaultFieldValidateRuleGenerateFunc(define.FieldValidateGenerateConfig{
Field: "",
})
So(err, ShouldNotBeNil)
So(define.IsErr(err, define.ErrValidatorRuleFieldIsEmpty.Error()), ShouldBeTrue)
So(res, ShouldBeEmpty)
})
Convey("未传入任何字段验证规则", t, func() {
res, err := DefaultFieldValidateRuleGenerateFunc(define.FieldValidateGenerateConfig{
Field: "test",
})
So(err, ShouldBeError)
So(define.IsErr(err, define.ErrValidatorRuleGroupOrSimpleRuleAllEmpty.Error()), ShouldBeTrue)
So(res, ShouldBeEmpty)
})
Convey("传入SimpleRule", t, func() {
res, err := DefaultFieldValidateRuleGenerateFunc(define.FieldValidateGenerateConfig{
Field: "test",
RuleGroup: nil,
RuleSimple: define.GenerateRuleExpressConfig{
Rule: consts.ValidatorRuleCommonRequired,
ParamList: nil,
},
})
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
So(strings.HasPrefix(res, consts.ValidatorRuleCommonRequired.String()), ShouldBeTrue)
})
}

35
v10/define/err.go Normal file
View File

@ -0,0 +1,35 @@
// Package define ...
//
// Description : define ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-01-24 15:38
package define
import (
"errors"
"strings"
)
var (
ErrValidatorRuleIsEmpty = errors.New("validator rule is empty")
ErrValidatorRuleParamCntIsTooLess = errors.New("validate rule param count is less than min param cnt")
ErrValidatorRuleParamCntIsTooMore = errors.New("validate rule param count is more than min param cnt")
ErrValidatorRuleParamCntIsNotEven = errors.New("validate rule param count is not even")
ErrValidatorRuleGroupOrSimpleRuleAllEmpty = errors.New("validator rule group or simple rule all empty")
ErrValidatorRuleFieldIsEmpty = errors.New("field is empty")
)
// IsErr 是否指定类型Err
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:45 2025/1/24
func IsErr(err error, subMsg string) bool {
if nil == err {
return false
}
return strings.Contains(err.Error(), subMsg)
}

29
v10/define/err_test.go Normal file
View File

@ -0,0 +1,29 @@
// Package define ...
//
// Description : define ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-01-24 15:46
package define
import (
"errors"
. "github.com/smartystreets/goconvey/convey"
"testing"
)
func TestIsErr(t *testing.T) {
Convey("传入error为nil", t, func() {
isErrRes := IsErr(nil, "")
So(isErrRes, ShouldBeFalse)
})
Convey("传入error为test类型", t, func() {
isErrRes := IsErr(errors.New("aaatestbbb"), "test")
So(isErrRes, ShouldBeTrue)
})
Convey("传入error非test类型", t, func() {
isErrRes := IsErr(errors.New("aaatecccstbbb"), "test")
So(isErrRes, ShouldBeFalse)
})
}

View File

@ -0,0 +1,31 @@
// Package define ...
//
// Description : define ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-01-24 11:21
package define
import "git.zhangdeman.cn/zhangdeman/consts"
// FieldValidateGenerateConfig 字段验证规则生成的配置
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:23 2025/1/24
type FieldValidateGenerateConfig struct {
Field string `json:"field,omitempty"` // 字段
RuleGroup [][]GenerateRuleExpressConfig `json:"rule_group,omitempty"` // 规则的分组, 同组内为 && 条件, 组之间为 || 条件, 适用于复杂条件配置
RuleSimple GenerateRuleExpressConfig `json:"rule_simple,omitempty"` // 简单条件配置, 与 RuleGroup 至少配置一个
}
// GenerateRuleExpressConfig 生成规则验证表达式的配置
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:27 2025/1/24
type GenerateRuleExpressConfig struct {
Rule consts.ValidatorRule `json:"rule,omitempty"` // 条件配置
ParamList []any `json:"param_list,omitempty"` // 规则验证的参数列表
}

46
v10/init.go Normal file
View File

@ -0,0 +1,46 @@
// Package v10 ...
//
// Description : v10 ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-01-24 11:09
package v10
import (
"git.zhangdeman.cn/gateway/validator/v10/abstract"
openValidator "github.com/go-playground/validator/v10"
)
// validatorRuleExpressGenerateFunc 验证规则表达式生成方法
var validatorRuleExpressGenerateFunc abstract.IValidateRuleGenerateFunc = DefaultValidateRuleGenerateFunc
// validatorRuleExpressGenerateFunc 字段验证规则生成默认表达式
var fieldValidatorRuleExpressGenerateFunc abstract.IFieldValidateRuleGenerateFunc = DefaultFieldValidateRuleGenerateFunc
// 验证器实例
var validateInstance = openValidator.New()
// SetValidatorRuleExpressGenerateFunc 使用自定义的验证规则表达式函数覆盖默认的函数
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:11 2025/1/24
func SetValidatorRuleExpressGenerateFunc(generateFunc abstract.IValidateRuleGenerateFunc) {
if nil == generateFunc {
return
}
validatorRuleExpressGenerateFunc = generateFunc
}
// SetFieldValidatorRuleExpressGenerateFunc 字段默认表达式生成规则
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:56 2025/1/24
func SetFieldValidatorRuleExpressGenerateFunc(generateFunc abstract.IFieldValidateRuleGenerateFunc) {
if nil == generateFunc {
return
}
fieldValidatorRuleExpressGenerateFunc = generateFunc
}

90
v10/validate_value.go Normal file
View File

@ -0,0 +1,90 @@
// Package v10 ...
//
// Description : v10 ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-01-24 16:42
package v10
import (
"git.zhangdeman.cn/gateway/validator/v10/define"
"git.zhangdeman.cn/zhangdeman/wrapper"
"sync"
)
// ValidateVar 验证任意变量值
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:44 2025/1/24
func ValidateVar(inputVal any, ruleConfig define.FieldValidateGenerateConfig) error {
validateRuleExpress, err := fieldValidatorRuleExpressGenerateFunc(ruleConfig)
if nil != err {
return err
}
if err = validateInstance.Var(inputVal, validateRuleExpress); nil != err {
return err
}
return nil
}
// ValidateMap 验证Map数据
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:56 2025/1/24
//
// 参数:
// - inputMap: 输入的map数据
// - ruleConfigMap: map数据每一项的验证规则
//
// 返回值:
// - 验证结果表, key为验证的字段, val为验证的错误信息, 返回异常表长度为 0, 说明验证通过
func ValidateMap(inputMap map[string]any, ruleConfigMap map[string]define.FieldValidateGenerateConfig) map[string]error {
errTable := map[string]error{}
lock := &sync.RWMutex{}
wg := &sync.WaitGroup{}
wg.Add(len(inputMap))
for mapKey, mapVal := range inputMap {
go func(key string, val any) {
defer wg.Done()
if _, exist := ruleConfigMap[mapKey]; !exist {
// 未传入验证规则, 不验证
return
}
if err := ValidateVar(val, ruleConfigMap[key]); nil != err {
// 验证失败
lock.Lock()
defer lock.Unlock()
errTable[key] = err
}
}(mapKey, mapVal)
}
wg.Wait()
return errTable
}
// ValidateDynamicStruct 验证动态结构体
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:28 2025/1/24
func ValidateDynamicStruct(inputMap map[string]any, ruleConfigMap map[string]define.FieldValidateGenerateConfig) error {
realMapData := make(map[string]any)
tagMap := make(map[string]string)
for mapKey, mapVal := range inputMap {
if _, exist := ruleConfigMap[mapKey]; !exist {
continue
}
realMapData[mapKey] = mapVal
express, err := fieldValidatorRuleExpressGenerateFunc(ruleConfigMap[mapKey])
if nil != err {
return err
}
tagMap[mapKey] = "validate:\"" + express + "\""
}
dynamicStruct := wrapper.NewMap2DynamicStruct(realMapData, tagMap)
structVal := dynamicStruct.ToStructDefaultValue()
return validateInstance.Struct(structVal)
}

View File

@ -0,0 +1,39 @@
// Package v10 ...
//
// Description : v10 ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-01-24 17:29
package v10
import (
"fmt"
"git.zhangdeman.cn/gateway/validator/v10/define"
"git.zhangdeman.cn/zhangdeman/consts"
"testing"
)
func TestValidateDynamicStruct(t *testing.T) {
err := ValidateDynamicStruct(map[string]any{
"name": "zhang",
"age": 15,
}, map[string]define.FieldValidateGenerateConfig{
"name": {
Field: "name",
RuleGroup: nil,
RuleSimple: define.GenerateRuleExpressConfig{
Rule: consts.ValidatorRuleCommonRequired,
},
},
"age": {
Field: "age",
RuleGroup: nil,
RuleSimple: define.GenerateRuleExpressConfig{
Rule: consts.ValidatorRuleCommonMax,
ParamList: []any{17},
},
},
})
fmt.Println(err)
}