Compare commits
13 Commits
d87fb61db5
...
master
Author | SHA1 | Date | |
---|---|---|---|
1e8f97b030 | |||
97f45e30a6 | |||
da9aa14f0e | |||
bc555966fa | |||
0ece3237d7 | |||
4367435ab7 | |||
0e090ee488 | |||
09c09a9621 | |||
d3be2ddb2d | |||
4c70ca6f84 | |||
974063eb26 | |||
c35d379a26 | |||
e5b2e1a377 |
@ -7,6 +7,10 @@
|
||||
// Date : 2024-04-29 10:51
|
||||
package define
|
||||
|
||||
import (
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
)
|
||||
|
||||
// FieldRule 字段验证规则
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
@ -14,7 +18,7 @@ package define
|
||||
// Date : 10:52 2024/4/29
|
||||
type FieldRule struct {
|
||||
Path string `json:"path"` // 字段路径
|
||||
Type string `json:"type"` // 数据类型, 具体枚举值参见 git.zhangdeman.cn/zhangdeman/consts
|
||||
Type consts.DataType `json:"type"` // 数据类型, 具体枚举值参见 git.zhangdeman.cn/zhangdeman/consts
|
||||
DisableRewrite bool `json:"disable_rewrite"` // 验证完相关数据类型之后, 不要重新给字段赋值
|
||||
DefaultValue any `json:"default_value"` // 默认值, 统一以字符串传入, 会转为最终设置的类型
|
||||
IsRequired bool `json:"is_required"` // 是否必传
|
||||
@ -35,9 +39,9 @@ type FieldRule struct {
|
||||
//
|
||||
// Date : 10:58 2024/4/29
|
||||
type RequiredCondition struct {
|
||||
DependOnField string `json:"depend_on_field"` // 依赖数据源中的那一个字段
|
||||
DependOnFieldType string `json:"depend_on_field_type"` // 依赖数据源数据类型
|
||||
DependOnFieldStatus []string `json:"depend_on_field_status"` // 依赖数据状态 : NOT_FOUND / IS_NIL / IS_ZERO / IS_EMPTY / IS_FALSE
|
||||
DependOnField string `json:"depend_on_field"` // 依赖数据源中的那一个字段
|
||||
DependOnFieldType consts.DataType `json:"depend_on_field_type"` // 依赖数据源数据类型
|
||||
DependOnFieldStatus []string `json:"depend_on_field_status"` // 依赖数据状态 : NOT_FOUND / IS_NIL / IS_ZERO / IS_EMPTY / IS_FALSE
|
||||
}
|
||||
|
||||
// ValueLimit 取值的限制
|
||||
|
11
go.mod
11
go.mod
@ -3,19 +3,18 @@ module git.zhangdeman.cn/gateway/validator
|
||||
go 1.22.2
|
||||
|
||||
require (
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240924065029-c865046cd9e7
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240618035451-8d48a6bd39dd
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321102241-d6e86b64f7ca
|
||||
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-20240924063449-ef80c6cb79d1
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/tidwall/gjson v1.17.3
|
||||
github.com/tidwall/gjson v1.18.0
|
||||
github.com/tidwall/sjson v1.2.5
|
||||
)
|
||||
|
||||
require (
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 // indirect
|
||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect
|
||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
|
54
go.sum
54
go.sum
@ -1,47 +1,15 @@
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240501142503-e31a270e50cc h1:kPz9xiUVruM8kwbUUVpxyCTX8pGgyKt60K5zX77oyC4=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240501142503-e31a270e50cc/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec h1:ENemx9RGAU9nqpPYC4S6C/Dnw9gwcx96+sTISG/6rsY=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240608104035-feddc6a70f9d h1:qKou2RVGqRd7ojAHq2H8xTxfwayjYvfn35Rk+Fz0+zU=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240608104035-feddc6a70f9d/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240623031247-2fea122027a7 h1:f04tDgg1+cWuoH+vkMeKtJ+glq2WhLG20MKFjogz8gQ=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240623031247-2fea122027a7/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240709134122-e1e2a2e421de h1:ksjcMHupU0Bw0BJxJp3dajmWqGdqV7k2eVohN5O3S9Q=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240709134122-e1e2a2e421de/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240823041145-d4df71cf37e5 h1:pmIHln0gWW+5xAB762h3WDsRkZuYLUDndvJDsGMKoOY=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240823041145-d4df71cf37e5/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240924065029-c865046cd9e7 h1:tyCPCMK+68PZ0axZylQHitMVp1d5mzNr9/YqMHXqo+A=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240924065029-c865046cd9e7/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 h1:I/wOsRpCSRkU9vo1u703slQsmK0wnNeZzsWQOGtIAG0=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211/go.mod h1:SrtvrQRdzt+8KfYzvosH++gWxo2ShPTzR1m3VQ6uX7U=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321102241-d6e86b64f7ca h1:uxjzbY5fDozjyK6jkoQtuQouVTcVfXjbe3chARYSjRM=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321102241-d6e86b64f7ca/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
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-20240325080031-1f58204e8687 h1:uQcGqdzi4UdpZlp4f4FUPeBqoygP58pEKJkmN3ROsE0=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687/go.mod h1:gf7SW2TXATgux8pfdFedMkXWv2515OtIIM/5c4atkFw=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240618035451-8d48a6bd39dd h1:2Y37waOVCmVvx0Rp8VGEptE2/2JVMImtxB4dKKDk/3w=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240618035451-8d48a6bd39dd/go.mod h1:6+7whkCmb4sJDIfH3HxNuXRveaM0gCCNWd2uXZqNtIE=
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253 h1:GO3oZa5a2sqwAzGcLDJtQzmshSWRmoP7IDS8bwFqvC4=
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
||||
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-20240422034417-8c922be06d95 h1:3lO4ap9p7kEA+4yL5ojG9mAWsz5sY28Nu2tSzAZEehw=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240422034417-8c922be06d95/go.mod h1:Fo4XOiZPua4E4/Qzy3ZYS5zyd15bS/lsb3t6S6PQFGY=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240506070032-e228983e7306 h1:Iy36ouA7TecVwBY1QTJfWIYNU2d39+APEfOhBC4gvic=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240506070032-e228983e7306/go.mod h1:7vFN7QrHLLI/iN7ZrJSU0bw/7TyaYjVQ4+clYuIoRrY=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240520124754-3faebb9145e3 h1:fDDWQV3Xu/ntjrtKjwK30URPHr4kJJpqZocw52x+DKw=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240520124754-3faebb9145e3/go.mod h1:7vFN7QrHLLI/iN7ZrJSU0bw/7TyaYjVQ4+clYuIoRrY=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240612083858-8d056baada2e h1:+PeWa2QdYBWnL32CfAAgy0dlaRCVNmYZDH4q+9w7Gfg=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240612083858-8d056baada2e/go.mod h1:US/pcq2vstE3iyxIHf53w8IeXKkZys7bj/ozLWkRYeE=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50 h1:olo34i2Gq5gX7bYPv5TR4X5l5CrYFtu9UCElkYlmL2c=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50/go.mod h1:US/pcq2vstE3iyxIHf53w8IeXKkZys7bj/ozLWkRYeE=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240823103024-c38d16dc28d3 h1:RcWNxrHmhZksZWrP/HLEwAM8uIIHYlPLQ20HnLzC+j0=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240823103024-c38d16dc28d3/go.mod h1:KcojKP22mv9/IZrQWlIBfa1EuBxtEOqfWMgN3SYK2N8=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240924063449-ef80c6cb79d1 h1:LYw8NJeWcOiyrGjH9weyxnaMit94MlIngL+uskbLjtw=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240924063449-ef80c6cb79d1/go.mod h1:+2qNxuRsfyfOvXk9HNwn+CmyPmmhhrQm/eIi1FDU1jw=
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740 h1:zPUoylfJTbc0EcxW+NEzOTBmoeFZ2I/rLFBnEzxb4Wk=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740/go.mod h1:1ct92dbVc49pmXusA/iGfcQUJzcYmJ+cjAhgc3sDv1I=
|
||||
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=
|
||||
@ -59,10 +27,8 @@ github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2
|
||||
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.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
|
||||
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94=
|
||||
github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
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=
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"git.zhangdeman.cn/gateway/validator/define"
|
||||
"git.zhangdeman.cn/zhangdeman/util"
|
||||
"git.zhangdeman.cn/zhangdeman/wrapper"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
@ -112,9 +113,24 @@ func handleString(inputVal any, rule *define.FieldRule) (string, error) {
|
||||
var (
|
||||
err error
|
||||
formatData string
|
||||
ok bool
|
||||
)
|
||||
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
||||
return "", err
|
||||
|
||||
if formatData, ok = inputVal.(string); !ok {
|
||||
// 传入的不是string类型
|
||||
if rule.DisableAutoConvert {
|
||||
// 禁用类型转换
|
||||
return "", fmt.Errorf("%v : filed type is %v, data value auto convert is disabled, input value type is %v", rule.Path, rule.Type, reflect.TypeOf(inputVal).Kind().String())
|
||||
}
|
||||
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
// 判断空字符串
|
||||
if !rule.AllowEmpty && formatData == "" && rule.IsRequired {
|
||||
// 必传且不允许空字符串
|
||||
return "", fmt.Errorf("%v : data type is string empty, field is required and empty value is not allowed", rule.Path)
|
||||
}
|
||||
if nil == rule.ValueLimit {
|
||||
return formatData, nil
|
||||
|
@ -26,7 +26,7 @@ func Test_handleFloat(t *testing.T) {
|
||||
as := assert.New(t)
|
||||
checkRule := &define.FieldRule{
|
||||
Path: "test_float",
|
||||
Type: consts.DataTypeFloat,
|
||||
Type: consts.DataTypeFloat64,
|
||||
DisableRewrite: false,
|
||||
DefaultValue: "",
|
||||
IsRequired: false,
|
||||
|
@ -141,7 +141,7 @@ func handleMapAnyAny(inputVal any, rule *define.FieldRule) (map[any]any, error)
|
||||
if inputValStr, ok := inputVal.(string); ok {
|
||||
jsonRes = gjson.Parse(inputValStr)
|
||||
} else {
|
||||
jsonRes = gjson.Parse(serialize.JSON.MarshalForString(inputVal))
|
||||
jsonRes = gjson.Parse(serialize.JSON.MarshalForStringIgnoreError(inputVal))
|
||||
}
|
||||
|
||||
if !jsonRes.IsObject() {
|
||||
@ -176,7 +176,7 @@ func strOrMapConvert(inputVal any, mapConfig *define.MapConfig, receiver any) er
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
byteData := serialize.JSON.MarshalForByte(inputVal)
|
||||
byteData := serialize.JSON.MarshalForByteIgnoreError(inputVal)
|
||||
if err = serialize.JSON.UnmarshalWithNumber(byteData, receiver); nil != err {
|
||||
return err
|
||||
}
|
||||
@ -195,7 +195,7 @@ func strOrMapConvert(inputVal any, mapConfig *define.MapConfig, receiver any) er
|
||||
}
|
||||
|
||||
if mapConfig.Mode == consts.DataMapModelReal {
|
||||
byteData := serialize.JSON.MarshalForByte(inputVal)
|
||||
byteData := serialize.JSON.MarshalForByteIgnoreError(inputVal)
|
||||
if err = serialize.JSON.UnmarshalWithNumber(byteData, receiver); nil != err {
|
||||
return err
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ func handleSliceSlice(inputValue interface{}, rule *define.FieldRule) ([][]any,
|
||||
}
|
||||
sliceSlice := make([][]any, 0)
|
||||
for _, item := range anySlice {
|
||||
byteData := serialize.JSON.MarshalForByte(item)
|
||||
byteData := serialize.JSON.MarshalForByteIgnoreError(item)
|
||||
res := make([]any, 0)
|
||||
if err = serialize.JSON.UnmarshalWithNumber(byteData, &res); nil != err {
|
||||
return nil, fmt.Errorf("%v : data type is expect [][]any, but convert fail : %v", rule.Path, err.Error())
|
||||
@ -154,7 +154,7 @@ func handleSliceMapAny(inputValue interface{}, rule *define.FieldRule) ([]map[an
|
||||
}
|
||||
mapSlice := make([]map[any]any, 0)
|
||||
for _, item := range anySlice {
|
||||
byteData := serialize.JSON.MarshalForByte(item)
|
||||
byteData := serialize.JSON.MarshalForByteIgnoreError(item)
|
||||
jsonRes := gjson.ParseBytes(byteData)
|
||||
res := make(map[any]any)
|
||||
jsonRes.ForEach(func(key, value gjson.Result) bool {
|
||||
@ -181,7 +181,7 @@ func handleSliceMapString(inputValue interface{}, rule *define.FieldRule) ([]map
|
||||
}
|
||||
mapSlice := make([]map[string]any, 0)
|
||||
for _, item := range anySlice {
|
||||
byteData := serialize.JSON.MarshalForByte(item)
|
||||
byteData := serialize.JSON.MarshalForByteIgnoreError(item)
|
||||
jsonRes := gjson.ParseBytes(byteData)
|
||||
res := make(map[string]any)
|
||||
jsonRes.ForEach(func(key, value gjson.Result) bool {
|
||||
@ -204,7 +204,7 @@ func handleSlice(inputValue interface{}, rule *define.FieldRule) ([]any, error)
|
||||
return nil, fmt.Errorf("%v : data type is expect slice or string, but get %v", rule.Path, inputValType.String())
|
||||
}
|
||||
if inputValType == reflect.Slice {
|
||||
inputValue = serialize.JSON.MarshalForString(inputValue)
|
||||
inputValue = serialize.JSON.MarshalForStringIgnoreError(inputValue)
|
||||
// 重置配置
|
||||
if nil == rule.SliceConfig {
|
||||
rule.SliceConfig = &define.SliceConfig{
|
||||
|
@ -7,14 +7,17 @@
|
||||
// Date : 2024-04-29 12:18
|
||||
package validator
|
||||
|
||||
import "git.zhangdeman.cn/gateway/validator/define"
|
||||
import (
|
||||
"git.zhangdeman.cn/gateway/validator/define"
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
)
|
||||
|
||||
// NewDefaultFieldRule ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 14:01 2024/4/29
|
||||
func NewDefaultFieldRule(path string, dataType string, isRequired bool, defaultValue string) *define.FieldRule {
|
||||
func NewDefaultFieldRule(path string, dataType consts.DataType, isRequired bool, defaultValue string) *define.FieldRule {
|
||||
r := &define.FieldRule{
|
||||
Path: path,
|
||||
Type: dataType,
|
||||
|
23
run.go
23
run.go
@ -126,7 +126,7 @@ func checkRuleConditionRequiredRule(sourceData []byte, rule *define.FieldRule) {
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:59 2024/4/29
|
||||
func getDataStatus(val gjson.Result, dataType string) string {
|
||||
func getDataStatus(val gjson.Result, dataType consts.DataType) string {
|
||||
if !val.Exists() {
|
||||
return consts.DataStatusNotFound
|
||||
}
|
||||
@ -135,24 +135,24 @@ func getDataStatus(val gjson.Result, dataType string) string {
|
||||
if len(val.String()) == 0 {
|
||||
return consts.DataStatusIsEmpty
|
||||
}
|
||||
case consts.DataTypeFloat:
|
||||
case consts.DataTypeFloat64:
|
||||
fallthrough
|
||||
case consts.DataTypeInt:
|
||||
if val.Float() == 0 {
|
||||
return consts.DataStatusIsZero
|
||||
}
|
||||
default:
|
||||
if strings.HasPrefix(dataType, "[]") {
|
||||
if strings.HasPrefix(dataType.String(), "[]") {
|
||||
// 数组
|
||||
if len(val.Array()) == 0 {
|
||||
return consts.DataStatusIsEmpty
|
||||
}
|
||||
} else if strings.HasPrefix(dataType, "map") {
|
||||
} else if strings.HasPrefix(dataType.String(), "map") {
|
||||
// 对象
|
||||
if len(val.Map()) == 0 {
|
||||
return consts.DataStatusIsEmpty
|
||||
}
|
||||
} else if strings.HasPrefix(dataType, "*") {
|
||||
} else if strings.HasPrefix(dataType.String(), "*") {
|
||||
// 指针类型
|
||||
if nil == val.Value() {
|
||||
return consts.DataStatusIsNil
|
||||
@ -227,7 +227,7 @@ func validate(sourceData []byte, val gjson.Result, rule *define.FieldRule) (any,
|
||||
if rule.IsRequired {
|
||||
return nil, fmt.Errorf("%v : field is required, but not found", rule.Path)
|
||||
}
|
||||
if strings.HasSuffix(rule.Type, "_ptr") {
|
||||
if strings.HasSuffix(rule.Type.String(), "_ptr") {
|
||||
// 指针类型数据, 无需验证
|
||||
return nil, nil
|
||||
}
|
||||
@ -246,10 +246,13 @@ func validate(sourceData []byte, val gjson.Result, rule *define.FieldRule) (any,
|
||||
//
|
||||
// Date : 14:43 2024/4/29
|
||||
func handleData(inputVal any, rule *define.FieldRule) (any, error) {
|
||||
rule.Type = strings.ToLower(rule.Type)
|
||||
rule.Type = consts.DataType(strings.ToLower(rule.Type.String()))
|
||||
if !rule.Type.IsValid() {
|
||||
return nil, fmt.Errorf("%v : data type %v is invalid", rule.Path, rule.Type.String())
|
||||
}
|
||||
// 处理真实的map和序列化之后的map
|
||||
if strings.HasPrefix(rule.Type, "map") {
|
||||
if strings.HasSuffix(rule.Type, "_marshal") {
|
||||
if strings.HasPrefix(rule.Type.String(), "map") {
|
||||
if strings.HasSuffix(rule.Type.String(), "_marshal") {
|
||||
rule.MapConfig = &define.MapConfig{Mode: consts.DataMapModelMarshal}
|
||||
} else {
|
||||
rule.MapConfig = &define.MapConfig{Mode: consts.DataMapModelReal}
|
||||
@ -259,7 +262,7 @@ func handleData(inputVal any, rule *define.FieldRule) (any, error) {
|
||||
switch rule.Type {
|
||||
case consts.DataTypeAny: // 任意类型
|
||||
return inputVal, nil
|
||||
case consts.DataTypeFloat, consts.DataTypeFloatPtr: // float数据
|
||||
case consts.DataTypeFloat32, consts.DataTypeFloat32Ptr, consts.DataTypeFloat64, consts.DataTypeFloat64Ptr: // float数据
|
||||
return handleFloat(inputVal, rule)
|
||||
case consts.DataTypeInt, consts.DataTypeIntPtr: // int类型
|
||||
return handleInt(inputVal, rule)
|
||||
|
180
run_test.go
180
run_test.go
@ -8,37 +8,177 @@
|
||||
package validator
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.zhangdeman.cn/gateway/validator/define"
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tidwall/gjson"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
// TestRunString 测试字符串类型
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:48 2024/11/1
|
||||
func TestRunString(t *testing.T) {
|
||||
sourceData := map[string]interface{}{
|
||||
"name": "白茶清欢",
|
||||
}
|
||||
_ = Run(sourceData, nil)
|
||||
byteData, _ := json.Marshal(sourceData)
|
||||
fmt.Println(string(byteData))
|
||||
ruleListForNotFound := []*define.FieldRule{
|
||||
&define.FieldRule{
|
||||
Path: "name1",
|
||||
Type: "string",
|
||||
DisableRewrite: false,
|
||||
DefaultValue: nil,
|
||||
IsRequired: true,
|
||||
AllowEmpty: false,
|
||||
AllowZero: false,
|
||||
AllowNil: false,
|
||||
DisableAutoTrimSpace: false,
|
||||
DisableAutoConvert: false,
|
||||
RequiredConditionGroup: nil,
|
||||
ValueLimit: nil,
|
||||
SliceConfig: nil,
|
||||
MapConfig: nil,
|
||||
},
|
||||
}
|
||||
err := Run(sourceData, ruleListForNotFound, nil)
|
||||
if nil != err {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
assert.Error(t, err)
|
||||
|
||||
sourceData = map[string]interface{}{
|
||||
"name": "",
|
||||
}
|
||||
ruleListForEmpty := []*define.FieldRule{
|
||||
&define.FieldRule{
|
||||
Path: "name",
|
||||
Type: "string",
|
||||
DisableRewrite: false,
|
||||
DefaultValue: nil,
|
||||
IsRequired: true,
|
||||
AllowEmpty: false,
|
||||
AllowZero: false,
|
||||
AllowNil: false,
|
||||
DisableAutoTrimSpace: false,
|
||||
DisableAutoConvert: false,
|
||||
},
|
||||
}
|
||||
|
||||
err = Run(sourceData, ruleListForEmpty, nil)
|
||||
if nil != err {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
assert.Error(t, err)
|
||||
|
||||
sourceData = map[string]interface{}{
|
||||
"name": 18,
|
||||
}
|
||||
ruleListForDisableAutoConvert := []*define.FieldRule{
|
||||
&define.FieldRule{
|
||||
Path: "name",
|
||||
Type: "string",
|
||||
DisableRewrite: false,
|
||||
DefaultValue: nil,
|
||||
IsRequired: true,
|
||||
AllowEmpty: false,
|
||||
AllowZero: false,
|
||||
AllowNil: false,
|
||||
DisableAutoTrimSpace: false,
|
||||
DisableAutoConvert: true,
|
||||
},
|
||||
}
|
||||
err = Run(sourceData, ruleListForDisableAutoConvert, nil)
|
||||
if nil != err {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
assert.Error(t, err)
|
||||
|
||||
sourceData = map[string]interface{}{
|
||||
"name": " ",
|
||||
}
|
||||
ruleListForAllowTrim := []*define.FieldRule{
|
||||
&define.FieldRule{
|
||||
Path: "name",
|
||||
Type: "string",
|
||||
DisableRewrite: false,
|
||||
DefaultValue: nil,
|
||||
IsRequired: true,
|
||||
AllowEmpty: false,
|
||||
AllowZero: false,
|
||||
AllowNil: false,
|
||||
DisableAutoTrimSpace: false,
|
||||
DisableAutoConvert: true,
|
||||
},
|
||||
}
|
||||
err = Run(sourceData, ruleListForAllowTrim, nil)
|
||||
if nil != err {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
assert.Error(t, err)
|
||||
|
||||
sourceData = map[string]interface{}{
|
||||
"name": " ",
|
||||
}
|
||||
ruleListForDisableTrim := []*define.FieldRule{
|
||||
&define.FieldRule{
|
||||
Path: "name",
|
||||
Type: "string",
|
||||
DisableRewrite: false,
|
||||
DefaultValue: nil,
|
||||
IsRequired: true,
|
||||
AllowEmpty: false,
|
||||
AllowZero: false,
|
||||
AllowNil: false,
|
||||
DisableAutoTrimSpace: true,
|
||||
DisableAutoConvert: true,
|
||||
},
|
||||
}
|
||||
err = Run(sourceData, ruleListForDisableTrim, nil)
|
||||
if nil != err {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func Test_getDataStatus(t *testing.T) {
|
||||
type args struct {
|
||||
val gjson.Result
|
||||
dataType string
|
||||
// TestRunFieldDepend 测试字段依赖关系
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 18:40 2024/11/1
|
||||
func TestRunFieldDepend(t *testing.T) {
|
||||
sourceData := map[string]interface{}{
|
||||
"name": "",
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
ruleListForDepend := []*define.FieldRule{
|
||||
&define.FieldRule{
|
||||
Path: "name",
|
||||
Type: "string",
|
||||
DisableRewrite: false,
|
||||
DefaultValue: nil,
|
||||
IsRequired: false,
|
||||
AllowEmpty: false,
|
||||
AllowZero: false,
|
||||
AllowNil: false,
|
||||
DisableAutoTrimSpace: false,
|
||||
DisableAutoConvert: false,
|
||||
RequiredConditionGroup: [][]define.RequiredCondition{
|
||||
[]define.RequiredCondition{
|
||||
define.RequiredCondition{
|
||||
DependOnField: "age",
|
||||
DependOnFieldType: "int",
|
||||
DependOnFieldStatus: []string{consts.DataStatusIsEmpty, consts.DataStatusIsNil, consts.DataStatusNotFound},
|
||||
},
|
||||
},
|
||||
},
|
||||
ValueLimit: nil,
|
||||
SliceConfig: nil,
|
||||
MapConfig: nil,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equalf(t, tt.want, getDataStatus(tt.args.val, tt.args.dataType), "getDataStatus(%v, %v)", tt.args.val, tt.args.dataType)
|
||||
})
|
||||
err := Run(sourceData, ruleListForDepend, nil)
|
||||
if nil != err {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user