基础类型, 无嵌套匿名结构体生成, 待解决寻址问题
This commit is contained in:
parent
393af3c4c3
commit
6b5bfaf666
20
define.go
20
define.go
@ -13,22 +13,24 @@ import (
|
||||
|
||||
const (
|
||||
TagErrMsg = "err" // json结构体中, 错误信息 tag 字段
|
||||
TagRule = "validator" // json结构体中, 验证规则 rule 字段
|
||||
TagValidate = "validator" // json结构体中, 验证规则 rule 字段
|
||||
TagDefaultValue = "d" // json结构体中默认值标签
|
||||
)
|
||||
|
||||
// Rule 规则定义
|
||||
type Rule struct {
|
||||
Tag string `json:"tag" dc:"规则标签,如:required, email, phone, etc."` // 规则标签,如:required, email, phone, etc.
|
||||
Args []string `json:"args" dc:"规则参数"` // 规则参数,如: Tag=min, Args=[1], 则会转化成验证规则 min=1
|
||||
Errmsg string `json:"errmsg" dc:"规则验证不通过时, 报错的信息"` // 规则验证不通过时, 报错的信息
|
||||
Tag string `json:"tag" dc:"规则标签,如:required, email, phone, etc."` // 规则标签,如:required, email, phone, etc.
|
||||
Args []string `json:"args" dc:"规则参数"` // 规则参数,如: Tag=min, Args=[1], 则会转化成验证规则 min=1
|
||||
}
|
||||
|
||||
// StructField 结构体字段定义
|
||||
type StructField struct {
|
||||
JsonTag string `json:"json_tag" dc:"字段对外输出的json标签"` // 结构体字段名称
|
||||
Type consts.DataType `json:"type" dc:"字段的数据类型"` // 字段的数据类型
|
||||
Required bool `json:"required" dc:"是否必传"` // 对应验证规则的 required 属性, 在非必传的情况下, 字段不存在, 不会进行规则验证, 字段存在, 才会进行验证, Required == false 时, 会在 RuleList 检测是否有required 规则
|
||||
RuleList []Rule `json:"rule_list" dc:"字段规则列表"` // 字段规则列表
|
||||
DefaultValue string `json:"default_value" dc:"字段默认值"` // 字段默认值, 仅对非必传字段生效, 统一用字符串类型, 后面会转换成 FieldType 类型
|
||||
JsonTag string `json:"json_tag" dc:"字段对外输出的json标签"` // 结构体字段名称, 不单独设置, 从 TargetPath 解析
|
||||
Type consts.DataType `json:"type" dc:"字段的数据类型"` // 字段的数据类型
|
||||
Required bool `json:"required" dc:"是否必传"` // 对应验证规则的 required 属性, 在非必传的情况下, 字段不存在, 不会进行规则验证, 字段存在, 才会进行验证, Required == false 时, 会在 RuleList 检测是否有required 规则
|
||||
RuleList []Rule `json:"rule_list" dc:"字段规则列表"` // 字段规则列表
|
||||
DefaultValue string `json:"default_value" dc:"字段默认值"` // 字段默认值, 仅对非必传字段生效, 统一用字符串类型, 后面会转换成 FieldType 类型
|
||||
SourcePath string `json:"source_path" dc:"读取数据的数据源路径"` // 读取数据的数据源路径
|
||||
TargetPath string `json:"target_path" dc:"数据设置哪一个路径"` // 目标数据路径
|
||||
Errmsg string `json:"errmsg" dc:"规则验证不通过时, 报错的信息"` // 规则验证不通过时, 报错的信息
|
||||
}
|
||||
|
33
go.mod
33
go.mod
@ -2,4 +2,35 @@ module git.zhangdeman.cn/gateway/validate
|
||||
|
||||
go 1.24.1
|
||||
|
||||
require git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250227040546-863c03f34bb8 // indirect
|
||||
require (
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250227040546-863c03f34bb8
|
||||
git.zhangdeman.cn/zhangdeman/json_filter v0.0.0-20241205105007-b8c8c9d4338c
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250302133417-c1588abcb436
|
||||
github.com/tidwall/gjson v1.18.0
|
||||
)
|
||||
|
||||
require (
|
||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd // indirect
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e // indirect
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // 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/go-playground/validator/v10 v10.25.0 // 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/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.36.0 // indirect
|
||||
golang.org/x/net v0.37.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
replace git.zhangdeman.cn/zhangdeman/wrapper => ../wrapper
|
||||
|
57
go.sum
57
go.sum
@ -1,2 +1,59 @@
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250227040546-863c03f34bb8 h1:VEifPc+vkpEQoX9rj7zxmT1m+IA81XjOxe7+Z1aqWNM=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250227040546-863c03f34bb8/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/json_filter v0.0.0-20241205105007-b8c8c9d4338c h1:y8WLSdY8dBkKmazLt/XokW/LGz3hbdvNUdCUnsWXpRw=
|
||||
git.zhangdeman.cn/zhangdeman/json_filter v0.0.0-20241205105007-b8c8c9d4338c/go.mod h1:GzCzTobrpI6J94Cluj9gjN/o5ZdNEyrXQcfGfj05ohs=
|
||||
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-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=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.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/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.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0nmsZJxEAnFLNO8=
|
||||
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
|
||||
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=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ=
|
||||
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/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=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
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=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
190
validate.go
Normal file
190
validate.go
Normal file
@ -0,0 +1,190 @@
|
||||
// Package validate ...
|
||||
//
|
||||
// Description : validate ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2025-03-18 15:10
|
||||
package validate
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"git.zhangdeman.cn/zhangdeman/json_filter/gjson_hack"
|
||||
"git.zhangdeman.cn/zhangdeman/serialize"
|
||||
"git.zhangdeman.cn/zhangdeman/wrapper"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/tidwall/gjson"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var validatorInstance = validator.New()
|
||||
|
||||
// Run 执行参数验证
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:12 2025/3/18
|
||||
func Run(sourceData []byte, fieldList []StructField) ([]byte, error) {
|
||||
handleInstance := &handle{
|
||||
sourceData: sourceData,
|
||||
fieldList: fieldList,
|
||||
dynamicStruct: wrapper.NewDynamic(),
|
||||
}
|
||||
return handleInstance.Run()
|
||||
}
|
||||
|
||||
type handle struct {
|
||||
sourceData []byte
|
||||
fieldList []StructField
|
||||
dynamicStruct *wrapper.DynamicStruct
|
||||
}
|
||||
|
||||
// Run 执行验证
|
||||
func (h *handle) Run() ([]byte, error) {
|
||||
for _, field := range h.fieldList {
|
||||
if len(field.Errmsg) == 0 {
|
||||
field.Errmsg = field.JsonTag + " : 参数校验不通过"
|
||||
}
|
||||
required, hasRequired := h.checkRequired(field)
|
||||
field.Required = required
|
||||
if field.Required && !hasRequired {
|
||||
if nil == field.RuleList {
|
||||
field.RuleList = make([]Rule, 0)
|
||||
}
|
||||
field.RuleList = append(field.RuleList, Rule{
|
||||
Tag: consts.ValidatorRuleCommonRequired.String(),
|
||||
Args: nil,
|
||||
})
|
||||
}
|
||||
sourceValue, err := h.getSourceDataValue(field)
|
||||
if nil != err {
|
||||
return nil, err
|
||||
}
|
||||
if nil == sourceValue {
|
||||
// 没出现异常, 但是value为nil, 视作参数不存在处理
|
||||
continue
|
||||
}
|
||||
// fieldName := wrapper.String(field.JsonTag).SnakeCaseToCamel()
|
||||
h.dynamicStruct.AddAny(field.JsonTag, h.generateTag(field), "dynamic_struct", sourceValue)
|
||||
}
|
||||
val := h.dynamicStruct.ToStructDefaultValue()
|
||||
if err := serialize.JSON.Transition(h.dynamicStruct.MapData(), &val); nil != err {
|
||||
return nil, err
|
||||
}
|
||||
targetByte, _ := json.Marshal(val)
|
||||
err := validatorInstance.Struct(val)
|
||||
return targetByte, err
|
||||
}
|
||||
|
||||
// checkRequired 格式化必传参数
|
||||
// 返回值1, 是否必传
|
||||
// 返回值2, 校验规则中是否存在必传校验
|
||||
func (h *handle) checkRequired(field StructField) (bool, bool) {
|
||||
required := field.Required
|
||||
isHasRequiredRule := false
|
||||
for _, rule := range field.RuleList {
|
||||
if rule.Tag == consts.ValidatorRuleCommonRequired.String() {
|
||||
isHasRequiredRule = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if isHasRequiredRule {
|
||||
required = true
|
||||
}
|
||||
if required && !isHasRequiredRule {
|
||||
// 必传, 但是没有必传校验规则
|
||||
return true, true
|
||||
}
|
||||
return true, false
|
||||
}
|
||||
|
||||
// getSourceDataValue 获取源数据值
|
||||
func (h *handle) getSourceDataValue(field StructField) (any, error) {
|
||||
sourceValue := gjson.GetBytes(h.sourceData, field.SourcePath)
|
||||
if !sourceValue.Exists() {
|
||||
if field.Required {
|
||||
return nil, errors.New(field.SourcePath + " is required")
|
||||
}
|
||||
if len(field.DefaultValue) > 0 {
|
||||
// 非必传, 且设置了默认值, 在数据源不存在时, 这只默认值
|
||||
sourceValue = gjson.Result{
|
||||
Type: gjson.String,
|
||||
Raw: field.DefaultValue,
|
||||
Str: field.DefaultValue,
|
||||
Num: 0,
|
||||
Index: 0,
|
||||
Indexes: nil,
|
||||
}
|
||||
} else {
|
||||
// 非必传, 且没有默认值, 就当做数据不存在
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
switch field.Type {
|
||||
case consts.DataTypeInt: // Int类型
|
||||
fallthrough
|
||||
case consts.DataTypeIntPtr: // Uint类型
|
||||
val, err := gjson_hack.Int(sourceValue)
|
||||
return val, err
|
||||
case consts.DataTypeUint:
|
||||
fallthrough
|
||||
case consts.DataTypeUintPtr: // Uint类型
|
||||
val, err := gjson_hack.Uint(sourceValue)
|
||||
return val, err
|
||||
case consts.DataTypeFloat:
|
||||
fallthrough
|
||||
case consts.DataTypeFloatPtr: // Float类型
|
||||
val, err := gjson_hack.Float64(sourceValue)
|
||||
return val, err
|
||||
case consts.DataTypeString: // String类型
|
||||
return sourceValue.String(), nil
|
||||
case consts.DataTypeBool: // Bool类型
|
||||
return sourceValue.Bool(), nil
|
||||
case consts.DataTypeSliceFloat: // Float slice
|
||||
val, err := gjson_hack.SliceFloat(sourceValue)
|
||||
return val, err
|
||||
case consts.DataTypeSliceInt: // Int slice
|
||||
val, err := gjson_hack.SliceInt(sourceValue)
|
||||
return val, err
|
||||
case consts.DataTypeSliceUint: // Uint slice
|
||||
val, err := gjson_hack.SliceUint(sourceValue)
|
||||
return val, err
|
||||
case consts.DataTypeSliceString: // String slice
|
||||
val, err := gjson_hack.SliceString(sourceValue)
|
||||
return val, err
|
||||
case consts.DataTypeSliceBool: // Bool slice
|
||||
val, err := gjson_hack.SliceBool(sourceValue)
|
||||
return val, err
|
||||
case consts.DataTypeMapStrAny: // Bool slice
|
||||
val, err := gjson_hack.MapStrAny[any](sourceValue)
|
||||
return val, err
|
||||
}
|
||||
return sourceValue.Value(), nil
|
||||
}
|
||||
|
||||
// 生成结构体的tag标签
|
||||
func (h *handle) generateTag(field StructField) string {
|
||||
tagList := []string{
|
||||
fmt.Sprintf(`json:"%s"`, field.JsonTag), // json tag
|
||||
}
|
||||
if len(field.Errmsg) == 0 {
|
||||
field.Errmsg = field.JsonTag + ": 参数校验不通过"
|
||||
}
|
||||
tagList = append(tagList, fmt.Sprintf(`%s:"%s"`, TagErrMsg, field.Errmsg)) // 错误信息tag
|
||||
validateRuleList := []string{}
|
||||
for _, itemRule := range field.RuleList {
|
||||
if len(itemRule.Args) == 0 {
|
||||
validateRuleList = append(validateRuleList, itemRule.Tag)
|
||||
} else {
|
||||
validateRuleList = append(validateRuleList, fmt.Sprintf("%s=%s", itemRule.Tag, strings.Join(itemRule.Args, " ")))
|
||||
}
|
||||
}
|
||||
// 验证规则tag
|
||||
tagList = append(tagList, fmt.Sprintf(`%s:"%s"`, TagValidate, strings.Join(validateRuleList, ",")))
|
||||
// 默认值
|
||||
tagList = append(tagList, fmt.Sprintf(`%s:"%s"`, TagDefaultValue, field.DefaultValue))
|
||||
return strings.Join(tagList, " ")
|
||||
}
|
48
validate_test.go
Normal file
48
validate_test.go
Normal file
@ -0,0 +1,48 @@
|
||||
// Package validate ...
|
||||
//
|
||||
// Description : validate ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2025-03-18 17:36
|
||||
package validate
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestRun_Simple_Data 无嵌套、无复杂数据类型的处理
|
||||
func TestRun_Simple_Data(t *testing.T) {
|
||||
testMap := map[string]any{
|
||||
"age": 180,
|
||||
"height": 179.5,
|
||||
"name": "baicha",
|
||||
}
|
||||
sourceByteData, _ := json.Marshal(testMap)
|
||||
fieldList := []StructField{
|
||||
{
|
||||
JsonTag: "age",
|
||||
Type: consts.DataTypeInt,
|
||||
Required: false,
|
||||
RuleList: []Rule{
|
||||
{
|
||||
Tag: "min",
|
||||
Args: []string{"1"},
|
||||
},
|
||||
{
|
||||
Tag: "max",
|
||||
Args: []string{"20"},
|
||||
},
|
||||
},
|
||||
DefaultValue: "",
|
||||
SourcePath: "age",
|
||||
TargetPath: "user_age",
|
||||
Errmsg: "年龄必须在[1,20]之间",
|
||||
},
|
||||
}
|
||||
_, err := Run(sourceByteData, fieldList)
|
||||
fmt.Println(err)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user