代码拆分文件
This commit is contained in:
parent
93117e13ea
commit
dcf3307726
139
handle_base.go
Normal file
139
handle_base.go
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
// Package validator ...
|
||||||
|
//
|
||||||
|
// Description : validator ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2024-05-01 22:34
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.zhangdeman.cn/gateway/validator/define"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/util"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/wrapper"
|
||||||
|
)
|
||||||
|
|
||||||
|
// handleFloat 处理float数据
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 15:29 2024/4/29
|
||||||
|
func handleFloat(inputVal any, rule *define.FieldRule) (float64, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
formatData float64
|
||||||
|
)
|
||||||
|
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if !rule.AllowZero {
|
||||||
|
return 0, fmt.Errorf("%v : field type is float, but zero val is not allowed", rule.Path)
|
||||||
|
}
|
||||||
|
if nil == rule.ValueLimit {
|
||||||
|
return formatData, nil
|
||||||
|
}
|
||||||
|
if nil != rule.ValueLimit.Min && formatData < *rule.ValueLimit.Min {
|
||||||
|
return 0, fmt.Errorf("%v : field type is float, min val is %v, real val is %v", rule.Path, *rule.ValueLimit.Min, formatData)
|
||||||
|
}
|
||||||
|
if nil != rule.ValueLimit.Max && formatData > *rule.ValueLimit.Max {
|
||||||
|
return 0, fmt.Errorf("%v : field type is float, max val is %v, real val is %v", rule.Path, *rule.ValueLimit.Max, formatData)
|
||||||
|
}
|
||||||
|
if len(rule.ValueLimit.EnumList) > 0 {
|
||||||
|
if wrapper.ArrayType(rule.ValueLimit.EnumList).Has(formatData) < 0 {
|
||||||
|
return 0, fmt.Errorf("%v : field type is float, real val is %v, is not in enum list", rule.Path, formatData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return formatData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleInt ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 15:36 2024/4/29
|
||||||
|
func handleInt(inputVal any, rule *define.FieldRule) (int64, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
formatData int64
|
||||||
|
)
|
||||||
|
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if _, err = handleFloat(formatData, rule); nil != err {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return formatData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleUint ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 21:28 2024/4/30
|
||||||
|
func handleUint(inputVal any, rule *define.FieldRule) (uint64, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
formatData uint64
|
||||||
|
)
|
||||||
|
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if _, err = handleFloat(formatData, rule); nil != err {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return formatData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleBool...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 21:26 2024/4/30
|
||||||
|
func handleBool(inputVal any, rule *define.FieldRule) (bool, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
formatData bool
|
||||||
|
)
|
||||||
|
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if _, err = handleFloat(formatData, rule); nil != err {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return formatData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleString ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 15:53 2024/4/29
|
||||||
|
func handleString(inputVal any, rule *define.FieldRule) (string, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
formatData string
|
||||||
|
)
|
||||||
|
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if nil == rule.ValueLimit {
|
||||||
|
return formatData, nil
|
||||||
|
}
|
||||||
|
if nil != rule.ValueLimit.Min {
|
||||||
|
if float64(len(formatData)) < *rule.ValueLimit.Min {
|
||||||
|
return "", fmt.Errorf("%v : data type is string, min length is %v, real length is %v", rule.Path, *rule.ValueLimit.Min, len(formatData))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if nil != rule.ValueLimit.Max {
|
||||||
|
if float64(len(formatData)) >= *rule.ValueLimit.Max {
|
||||||
|
return "", fmt.Errorf("%v : data type is string, max length is %v, real length is %v", rule.Path, *rule.ValueLimit.Max, len(formatData))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(rule.ValueLimit.EnumList) > 0 {
|
||||||
|
if wrapper.ArrayType(rule.ValueLimit.EnumList).Has(formatData) < 0 {
|
||||||
|
return "", fmt.Errorf("%v : data type is string, not in enum list, real val is %v", rule.Path, formatData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return formatData, nil
|
||||||
|
}
|
178
handle_map.go
Normal file
178
handle_map.go
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
// Package validator ...
|
||||||
|
//
|
||||||
|
// Description : validator ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2024-05-01 22:33
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.zhangdeman.cn/gateway/validator/define"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/serialize"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
// handleMapStringFloat ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 16:38 2024/4/29
|
||||||
|
func handleMapStringFloat(inputVal any, rule *define.FieldRule) (map[string]float64, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
res map[string]float64
|
||||||
|
)
|
||||||
|
|
||||||
|
if err = strOrMapConvert(inputVal, &res); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dataFieldTable := make(map[string]string)
|
||||||
|
for k, _ := range res {
|
||||||
|
dataFieldTable[k] = k
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = validateMap(dataFieldTable, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleMapStringAny ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 17:19 2024/4/29
|
||||||
|
func handleMapStringAny(inputVal any, rule *define.FieldRule) (map[string]any, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
res map[string]any
|
||||||
|
)
|
||||||
|
|
||||||
|
if err = strOrMapConvert(inputVal, &res); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dataFieldTable := make(map[string]string)
|
||||||
|
for k, _ := range res {
|
||||||
|
dataFieldTable[k] = k
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = validateMap(dataFieldTable, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleMapStringSlice...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 17:42 2024/4/29
|
||||||
|
func handleMapStringSlice(inputVal any, rule *define.FieldRule) (map[string][]any, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
res map[string][]any
|
||||||
|
)
|
||||||
|
|
||||||
|
if err = strOrMapConvert(inputVal, &res); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dataFieldTable := make(map[string]string)
|
||||||
|
for k, _ := range res {
|
||||||
|
dataFieldTable[k] = k
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = validateMap(dataFieldTable, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleMapAnyAny map[any]any处理
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 17:33 2024/4/29
|
||||||
|
func handleMapAnyAny(inputVal any, rule *define.FieldRule) (map[any]any, error) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
res = map[any]any{}
|
||||||
|
jsonRes gjson.Result
|
||||||
|
)
|
||||||
|
|
||||||
|
if inputValStr, ok := inputVal.(string); ok {
|
||||||
|
jsonRes = gjson.Parse(inputValStr)
|
||||||
|
} else {
|
||||||
|
jsonRes = gjson.Parse(serialize.JSON.MarshalForString(inputVal))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !jsonRes.IsObject() {
|
||||||
|
return nil, fmt.Errorf("%v : is not a map", rule.Path)
|
||||||
|
}
|
||||||
|
fieldTable := make(map[string]string)
|
||||||
|
jsonRes.ForEach(func(key, value gjson.Result) bool {
|
||||||
|
fieldTable[key.String()] = key.String()
|
||||||
|
res[key.Value()] = value.Value()
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
if err = validateMap(fieldTable, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// strOrMapConvert 字符串或map转map
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 17:26 2024/4/29
|
||||||
|
func strOrMapConvert(inputVal any, receiver any) error {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
if inputValStr, ok := inputVal.(string); ok {
|
||||||
|
if err = serialize.JSON.UnmarshalWithNumber([]byte(inputValStr), receiver); nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
byteData := serialize.JSON.MarshalForByte(inputVal)
|
||||||
|
if err = serialize.JSON.UnmarshalWithNumber(byteData, receiver); nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateMap 验证map数据
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 17:21 2024/4/29
|
||||||
|
func validateMap(dataFieldTable map[string]string, rule *define.FieldRule) error {
|
||||||
|
if nil == rule.ValueLimit {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if nil != rule.ValueLimit.Min && float64(len(dataFieldTable)) < *rule.ValueLimit.Min {
|
||||||
|
return fmt.Errorf("%v : data type is map, min item cnt is %v, real item cnt is %v", rule.Path, *rule.ValueLimit.Min, len(dataFieldTable))
|
||||||
|
}
|
||||||
|
if nil != rule.ValueLimit.Max && float64(len(dataFieldTable)) >= *rule.ValueLimit.Max {
|
||||||
|
return fmt.Errorf("%v : data type is map, max item cnt is %v, real item max is %v", rule.Path, *rule.ValueLimit.Max, len(dataFieldTable))
|
||||||
|
}
|
||||||
|
if nil != rule.ValueLimit.Map {
|
||||||
|
for _, itemField := range rule.ValueLimit.Map.IncludeFieldList {
|
||||||
|
if _, exist := dataFieldTable[itemField]; !exist {
|
||||||
|
return fmt.Errorf("%v : data type is map, %v field is required, but not found", rule.Path, itemField)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
305
handle_slice.go
Normal file
305
handle_slice.go
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
// Package validator ...
|
||||||
|
//
|
||||||
|
// Description : validator ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2024-05-01 22:32
|
||||||
|
package validator
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.zhangdeman.cn/gateway/validator/define"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/consts"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/serialize"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/util"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// handleSliceInt ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 22:30 2024/4/30
|
||||||
|
func handleSliceInt(inputValue interface{}, rule *define.FieldRule) ([]int64, error) {
|
||||||
|
var (
|
||||||
|
anySlice []any
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
intSlice := make([]int64, 0)
|
||||||
|
for _, item := range anySlice {
|
||||||
|
var itemInt int64
|
||||||
|
if err = util.ConvertAssign(&itemInt, item); nil != err {
|
||||||
|
return nil, fmt.Errorf("%v : data type expect int, but convert fail : %v", rule.Path, err.Error())
|
||||||
|
}
|
||||||
|
intSlice = append(intSlice, itemInt)
|
||||||
|
}
|
||||||
|
return intSlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleSliceUint ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 22:30 2024/4/30
|
||||||
|
func handleSliceUint(inputValue interface{}, rule *define.FieldRule) ([]uint64, error) {
|
||||||
|
var (
|
||||||
|
anySlice []any
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
uintSlice := make([]uint64, 0)
|
||||||
|
for _, item := range anySlice {
|
||||||
|
var itemUint uint64
|
||||||
|
if err = util.ConvertAssign(&itemUint, item); nil != err {
|
||||||
|
return nil, fmt.Errorf("%v : data type expect uint, but convert fail : %v", rule.Path, err.Error())
|
||||||
|
}
|
||||||
|
uintSlice = append(uintSlice, itemUint)
|
||||||
|
}
|
||||||
|
return uintSlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleSliceBool ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 22:30 2024/4/30
|
||||||
|
func handleSliceBool(inputValue interface{}, rule *define.FieldRule) ([]bool, error) {
|
||||||
|
var (
|
||||||
|
anySlice []any
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
boolSlice := make([]bool, 0)
|
||||||
|
for _, item := range anySlice {
|
||||||
|
var itemBool bool
|
||||||
|
if err = util.ConvertAssign(&itemBool, item); nil != err {
|
||||||
|
return nil, fmt.Errorf("%v : data type expect bool, but convert fail : %v", rule.Path, err.Error())
|
||||||
|
}
|
||||||
|
boolSlice = append(boolSlice, itemBool)
|
||||||
|
}
|
||||||
|
return boolSlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleSliceFloat ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 22:30 2024/4/30
|
||||||
|
func handleSliceFloat(inputValue interface{}, rule *define.FieldRule) ([]float64, error) {
|
||||||
|
var (
|
||||||
|
anySlice []any
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
floatSlice := make([]float64, 0)
|
||||||
|
for _, item := range anySlice {
|
||||||
|
var itemFloat float64
|
||||||
|
if err = util.ConvertAssign(&itemFloat, item); nil != err {
|
||||||
|
return nil, fmt.Errorf("%v : data type expect float, but convert fail : %v", rule.Path, err.Error())
|
||||||
|
}
|
||||||
|
floatSlice = append(floatSlice, itemFloat)
|
||||||
|
}
|
||||||
|
return floatSlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleSliceSlice ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 22:30 2024/4/30
|
||||||
|
func handleSliceSlice(inputValue interface{}, rule *define.FieldRule) ([][]any, error) {
|
||||||
|
var (
|
||||||
|
anySlice []any
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sliceSlice := make([][]any, 0)
|
||||||
|
for _, item := range anySlice {
|
||||||
|
byteData := serialize.JSON.MarshalForByte(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())
|
||||||
|
}
|
||||||
|
sliceSlice = append(sliceSlice, res)
|
||||||
|
}
|
||||||
|
return sliceSlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleSliceMapAny ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 22:30 2024/4/30
|
||||||
|
func handleSliceMapAny(inputValue interface{}, rule *define.FieldRule) ([]map[any]any, error) {
|
||||||
|
var (
|
||||||
|
anySlice []any
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mapSlice := make([]map[any]any, 0)
|
||||||
|
for _, item := range anySlice {
|
||||||
|
byteData := serialize.JSON.MarshalForByte(item)
|
||||||
|
jsonRes := gjson.ParseBytes(byteData)
|
||||||
|
res := make(map[any]any)
|
||||||
|
jsonRes.ForEach(func(key, value gjson.Result) bool {
|
||||||
|
res[key.Value()] = value.Value()
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
mapSlice = append(mapSlice, res)
|
||||||
|
}
|
||||||
|
return mapSlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleSliceMapString ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 21:33 2024/5/1
|
||||||
|
func handleSliceMapString(inputValue interface{}, rule *define.FieldRule) ([]map[string]any, error) {
|
||||||
|
var (
|
||||||
|
anySlice []any
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mapSlice := make([]map[string]any, 0)
|
||||||
|
for _, item := range anySlice {
|
||||||
|
byteData := serialize.JSON.MarshalForByte(item)
|
||||||
|
jsonRes := gjson.ParseBytes(byteData)
|
||||||
|
res := make(map[string]any)
|
||||||
|
jsonRes.ForEach(func(key, value gjson.Result) bool {
|
||||||
|
res[key.String()] = value.Value()
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
mapSlice = append(mapSlice, res)
|
||||||
|
}
|
||||||
|
return mapSlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleSlice 数组处理
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 21:30 2024/4/30
|
||||||
|
func handleSlice(inputValue interface{}, rule *define.FieldRule) ([]any, error) {
|
||||||
|
inputValType := reflect.TypeOf(inputValue).Kind()
|
||||||
|
if inputValType != reflect.Slice && inputValType != reflect.String {
|
||||||
|
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)
|
||||||
|
// 重置配置
|
||||||
|
if nil == rule.SliceConfig {
|
||||||
|
rule.SliceConfig = &define.SliceConfig{
|
||||||
|
Mode: consts.DataSliceModelMarshal,
|
||||||
|
DisableIgnoreEmpty: false,
|
||||||
|
DisableAutoConvert: false,
|
||||||
|
SplitChar: "",
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rule.SliceConfig.Mode = consts.DataSliceModelMarshal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
anySlice []any
|
||||||
|
)
|
||||||
|
|
||||||
|
if inputStr, ok := inputValue.(string); ok {
|
||||||
|
if anySlice, err = handleSliceString(inputStr, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err = validateSlice(anySlice, rule); nil != err {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return anySlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleSliceString ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 22:06 2024/4/30
|
||||||
|
func handleSliceString(inputStr string, rule *define.FieldRule) ([]any, error) {
|
||||||
|
if nil == rule.SliceConfig {
|
||||||
|
return nil, fmt.Errorf("%v : data type is slice, but get string", rule.Path)
|
||||||
|
}
|
||||||
|
if rule.SliceConfig.Mode == consts.DataSliceModelReal {
|
||||||
|
return nil, fmt.Errorf("%v : data type expect real slice, but get string", rule.Path)
|
||||||
|
}
|
||||||
|
if rule.SliceConfig.Mode == consts.DataSliceModelMarshal { // json序列化之后的
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
res []any
|
||||||
|
)
|
||||||
|
if err = serialize.JSON.UnmarshalWithNumber([]byte(inputStr), &res); nil != err {
|
||||||
|
return nil, fmt.Errorf("%v : data type expect marshal slice, but can not convert", rule.Path)
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
if rule.SliceConfig.Mode == consts.DataSliceModelWithSplitChar { // 指定字符串切割
|
||||||
|
strArr := strings.Split(inputStr, rule.SliceConfig.SplitChar)
|
||||||
|
anyArr := make([]any, 0)
|
||||||
|
for _, item := range strArr {
|
||||||
|
if !rule.SliceConfig.DisableIgnoreEmpty && len(item) == 0 {
|
||||||
|
// 没禁用忽略空字符串
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
anyArr = append(anyArr, item)
|
||||||
|
}
|
||||||
|
return anyArr, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("%v : data type is slice, but rule mode [%v] is not supported", rule.Path, rule.SliceConfig.Mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateSlice ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 09:39 2024/5/1
|
||||||
|
func validateSlice(anySlice []any, rule *define.FieldRule) error {
|
||||||
|
|
||||||
|
// 验证
|
||||||
|
if nil == rule.ValueLimit {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if nil != rule.ValueLimit.Min && float64(len(anySlice)) < *rule.ValueLimit.Min {
|
||||||
|
return fmt.Errorf("%v : data type is slice, min length is [%v], real length is [%v]", rule.Path, *rule.ValueLimit.Min, len(anySlice))
|
||||||
|
}
|
||||||
|
|
||||||
|
if nil != rule.ValueLimit.Max && float64(len(anySlice)) > *rule.ValueLimit.Min {
|
||||||
|
return fmt.Errorf("%v : data type is slice, max length is [%v], real length is [%v]", rule.Path, *rule.ValueLimit.Max, len(anySlice))
|
||||||
|
}
|
||||||
|
|
||||||
|
enumTable := make(map[string]bool)
|
||||||
|
for _, item := range rule.ValueLimit.EnumList {
|
||||||
|
enumTable[item] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, itemVal := range anySlice {
|
||||||
|
if _, exist := enumTable[fmt.Sprintf("%v", itemVal)]; !exist {
|
||||||
|
return fmt.Errorf("%v : data type is slice, slice value [%v] is not un enum list", rule.Path, itemVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
577
run.go
577
run.go
@ -13,12 +13,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"git.zhangdeman.cn/gateway/validator/define"
|
"git.zhangdeman.cn/gateway/validator/define"
|
||||||
"git.zhangdeman.cn/zhangdeman/consts"
|
"git.zhangdeman.cn/zhangdeman/consts"
|
||||||
"git.zhangdeman.cn/zhangdeman/serialize"
|
|
||||||
"git.zhangdeman.cn/zhangdeman/util"
|
|
||||||
"git.zhangdeman.cn/zhangdeman/wrapper"
|
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
"github.com/tidwall/sjson"
|
"github.com/tidwall/sjson"
|
||||||
"reflect"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -189,576 +185,3 @@ func handleData(inputVal any, rule *define.FieldRule) (any, error) {
|
|||||||
}
|
}
|
||||||
return nil, fmt.Errorf("%v : data type [%v] is not support", rule.Path, rule.Type)
|
return nil, fmt.Errorf("%v : data type [%v] is not support", rule.Path, rule.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleFloat 处理float数据
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 15:29 2024/4/29
|
|
||||||
func handleFloat(inputVal any, rule *define.FieldRule) (float64, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
formatData float64
|
|
||||||
)
|
|
||||||
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
if !rule.AllowZero {
|
|
||||||
return 0, fmt.Errorf("%v : field type is float, but zero val is not allowed", rule.Path)
|
|
||||||
}
|
|
||||||
if nil == rule.ValueLimit {
|
|
||||||
return formatData, nil
|
|
||||||
}
|
|
||||||
if nil != rule.ValueLimit.Min && formatData < *rule.ValueLimit.Min {
|
|
||||||
return 0, fmt.Errorf("%v : field type is float, min val is %v, real val is %v", rule.Path, *rule.ValueLimit.Min, formatData)
|
|
||||||
}
|
|
||||||
if nil != rule.ValueLimit.Max && formatData > *rule.ValueLimit.Max {
|
|
||||||
return 0, fmt.Errorf("%v : field type is float, max val is %v, real val is %v", rule.Path, *rule.ValueLimit.Max, formatData)
|
|
||||||
}
|
|
||||||
if len(rule.ValueLimit.EnumList) > 0 {
|
|
||||||
if wrapper.ArrayType(rule.ValueLimit.EnumList).Has(formatData) < 0 {
|
|
||||||
return 0, fmt.Errorf("%v : field type is float, real val is %v, is not in enum list", rule.Path, formatData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return formatData, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleInt ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 15:36 2024/4/29
|
|
||||||
func handleInt(inputVal any, rule *define.FieldRule) (int64, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
formatData int64
|
|
||||||
)
|
|
||||||
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
if _, err = handleFloat(formatData, rule); nil != err {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return formatData, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleUint ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 21:28 2024/4/30
|
|
||||||
func handleUint(inputVal any, rule *define.FieldRule) (uint64, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
formatData uint64
|
|
||||||
)
|
|
||||||
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
if _, err = handleFloat(formatData, rule); nil != err {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return formatData, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleBool...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 21:26 2024/4/30
|
|
||||||
func handleBool(inputVal any, rule *define.FieldRule) (bool, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
formatData bool
|
|
||||||
)
|
|
||||||
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if _, err = handleFloat(formatData, rule); nil != err {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return formatData, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleString ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 15:53 2024/4/29
|
|
||||||
func handleString(inputVal any, rule *define.FieldRule) (string, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
formatData string
|
|
||||||
)
|
|
||||||
if err = util.ConvertAssign(&formatData, inputVal); nil != err {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if nil == rule.ValueLimit {
|
|
||||||
return formatData, nil
|
|
||||||
}
|
|
||||||
if nil != rule.ValueLimit.Min {
|
|
||||||
if float64(len(formatData)) < *rule.ValueLimit.Min {
|
|
||||||
return "", fmt.Errorf("%v : data type is string, min length is %v, real length is %v", rule.Path, *rule.ValueLimit.Min, len(formatData))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if nil != rule.ValueLimit.Max {
|
|
||||||
if float64(len(formatData)) >= *rule.ValueLimit.Max {
|
|
||||||
return "", fmt.Errorf("%v : data type is string, max length is %v, real length is %v", rule.Path, *rule.ValueLimit.Max, len(formatData))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(rule.ValueLimit.EnumList) > 0 {
|
|
||||||
if wrapper.ArrayType(rule.ValueLimit.EnumList).Has(formatData) < 0 {
|
|
||||||
return "", fmt.Errorf("%v : data type is string, not in enum list, real val is %v", rule.Path, formatData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return formatData, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleMapStringFloat ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 16:38 2024/4/29
|
|
||||||
func handleMapStringFloat(inputVal any, rule *define.FieldRule) (map[string]float64, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
res map[string]float64
|
|
||||||
)
|
|
||||||
|
|
||||||
if err = strOrMapConvert(inputVal, &res); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
dataFieldTable := make(map[string]string)
|
|
||||||
for k, _ := range res {
|
|
||||||
dataFieldTable[k] = k
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = validateMap(dataFieldTable, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleMapStringAny ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 17:19 2024/4/29
|
|
||||||
func handleMapStringAny(inputVal any, rule *define.FieldRule) (map[string]any, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
res map[string]any
|
|
||||||
)
|
|
||||||
|
|
||||||
if err = strOrMapConvert(inputVal, &res); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
dataFieldTable := make(map[string]string)
|
|
||||||
for k, _ := range res {
|
|
||||||
dataFieldTable[k] = k
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = validateMap(dataFieldTable, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleMapStringSlice...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 17:42 2024/4/29
|
|
||||||
func handleMapStringSlice(inputVal any, rule *define.FieldRule) (map[string][]any, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
res map[string][]any
|
|
||||||
)
|
|
||||||
|
|
||||||
if err = strOrMapConvert(inputVal, &res); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
dataFieldTable := make(map[string]string)
|
|
||||||
for k, _ := range res {
|
|
||||||
dataFieldTable[k] = k
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = validateMap(dataFieldTable, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleMapAnyAny map[any]any处理
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 17:33 2024/4/29
|
|
||||||
func handleMapAnyAny(inputVal any, rule *define.FieldRule) (map[any]any, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
res = map[any]any{}
|
|
||||||
jsonRes gjson.Result
|
|
||||||
)
|
|
||||||
|
|
||||||
if inputValStr, ok := inputVal.(string); ok {
|
|
||||||
jsonRes = gjson.Parse(inputValStr)
|
|
||||||
} else {
|
|
||||||
jsonRes = gjson.Parse(serialize.JSON.MarshalForString(inputVal))
|
|
||||||
}
|
|
||||||
|
|
||||||
if !jsonRes.IsObject() {
|
|
||||||
return nil, fmt.Errorf("%v : is not a map", rule.Path)
|
|
||||||
}
|
|
||||||
fieldTable := make(map[string]string)
|
|
||||||
jsonRes.ForEach(func(key, value gjson.Result) bool {
|
|
||||||
fieldTable[key.String()] = key.String()
|
|
||||||
res[key.Value()] = value.Value()
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
if err = validateMap(fieldTable, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// strOrMapConvert 字符串或map转map
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 17:26 2024/4/29
|
|
||||||
func strOrMapConvert(inputVal any, receiver any) error {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
if inputValStr, ok := inputVal.(string); ok {
|
|
||||||
if err = serialize.JSON.UnmarshalWithNumber([]byte(inputValStr), receiver); nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
byteData := serialize.JSON.MarshalForByte(inputVal)
|
|
||||||
if err = serialize.JSON.UnmarshalWithNumber(byteData, receiver); nil != err {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// validateMap 验证map数据
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 17:21 2024/4/29
|
|
||||||
func validateMap(dataFieldTable map[string]string, rule *define.FieldRule) error {
|
|
||||||
if nil == rule.ValueLimit {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if nil != rule.ValueLimit.Min && float64(len(dataFieldTable)) < *rule.ValueLimit.Min {
|
|
||||||
return fmt.Errorf("%v : data type is map, min item cnt is %v, real item cnt is %v", rule.Path, *rule.ValueLimit.Min, len(dataFieldTable))
|
|
||||||
}
|
|
||||||
if nil != rule.ValueLimit.Max && float64(len(dataFieldTable)) >= *rule.ValueLimit.Max {
|
|
||||||
return fmt.Errorf("%v : data type is map, max item cnt is %v, real item max is %v", rule.Path, *rule.ValueLimit.Max, len(dataFieldTable))
|
|
||||||
}
|
|
||||||
if nil != rule.ValueLimit.Map {
|
|
||||||
for _, itemField := range rule.ValueLimit.Map.IncludeFieldList {
|
|
||||||
if _, exist := dataFieldTable[itemField]; !exist {
|
|
||||||
return fmt.Errorf("%v : data type is map, %v field is required, but not found", rule.Path, itemField)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleSliceInt ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 22:30 2024/4/30
|
|
||||||
func handleSliceInt(inputValue interface{}, rule *define.FieldRule) ([]int64, error) {
|
|
||||||
var (
|
|
||||||
anySlice []any
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
intSlice := make([]int64, 0)
|
|
||||||
for _, item := range anySlice {
|
|
||||||
var itemInt int64
|
|
||||||
if err = util.ConvertAssign(&itemInt, item); nil != err {
|
|
||||||
return nil, fmt.Errorf("%v : data type expect int, but convert fail : %v", rule.Path, err.Error())
|
|
||||||
}
|
|
||||||
intSlice = append(intSlice, itemInt)
|
|
||||||
}
|
|
||||||
return intSlice, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleSliceUint ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 22:30 2024/4/30
|
|
||||||
func handleSliceUint(inputValue interface{}, rule *define.FieldRule) ([]uint64, error) {
|
|
||||||
var (
|
|
||||||
anySlice []any
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
uintSlice := make([]uint64, 0)
|
|
||||||
for _, item := range anySlice {
|
|
||||||
var itemUint uint64
|
|
||||||
if err = util.ConvertAssign(&itemUint, item); nil != err {
|
|
||||||
return nil, fmt.Errorf("%v : data type expect uint, but convert fail : %v", rule.Path, err.Error())
|
|
||||||
}
|
|
||||||
uintSlice = append(uintSlice, itemUint)
|
|
||||||
}
|
|
||||||
return uintSlice, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleSliceBool ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 22:30 2024/4/30
|
|
||||||
func handleSliceBool(inputValue interface{}, rule *define.FieldRule) ([]bool, error) {
|
|
||||||
var (
|
|
||||||
anySlice []any
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
boolSlice := make([]bool, 0)
|
|
||||||
for _, item := range anySlice {
|
|
||||||
var itemBool bool
|
|
||||||
if err = util.ConvertAssign(&itemBool, item); nil != err {
|
|
||||||
return nil, fmt.Errorf("%v : data type expect bool, but convert fail : %v", rule.Path, err.Error())
|
|
||||||
}
|
|
||||||
boolSlice = append(boolSlice, itemBool)
|
|
||||||
}
|
|
||||||
return boolSlice, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleSliceFloat ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 22:30 2024/4/30
|
|
||||||
func handleSliceFloat(inputValue interface{}, rule *define.FieldRule) ([]float64, error) {
|
|
||||||
var (
|
|
||||||
anySlice []any
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
floatSlice := make([]float64, 0)
|
|
||||||
for _, item := range anySlice {
|
|
||||||
var itemFloat float64
|
|
||||||
if err = util.ConvertAssign(&itemFloat, item); nil != err {
|
|
||||||
return nil, fmt.Errorf("%v : data type expect float, but convert fail : %v", rule.Path, err.Error())
|
|
||||||
}
|
|
||||||
floatSlice = append(floatSlice, itemFloat)
|
|
||||||
}
|
|
||||||
return floatSlice, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleSliceSlice ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 22:30 2024/4/30
|
|
||||||
func handleSliceSlice(inputValue interface{}, rule *define.FieldRule) ([][]any, error) {
|
|
||||||
var (
|
|
||||||
anySlice []any
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
sliceSlice := make([][]any, 0)
|
|
||||||
for _, item := range anySlice {
|
|
||||||
byteData := serialize.JSON.MarshalForByte(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())
|
|
||||||
}
|
|
||||||
sliceSlice = append(sliceSlice, res)
|
|
||||||
}
|
|
||||||
return sliceSlice, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleSliceMapAny ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 22:30 2024/4/30
|
|
||||||
func handleSliceMapAny(inputValue interface{}, rule *define.FieldRule) ([]map[any]any, error) {
|
|
||||||
var (
|
|
||||||
anySlice []any
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
mapSlice := make([]map[any]any, 0)
|
|
||||||
for _, item := range anySlice {
|
|
||||||
byteData := serialize.JSON.MarshalForByte(item)
|
|
||||||
jsonRes := gjson.ParseBytes(byteData)
|
|
||||||
res := make(map[any]any)
|
|
||||||
jsonRes.ForEach(func(key, value gjson.Result) bool {
|
|
||||||
res[key.Value()] = value.Value()
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
mapSlice = append(mapSlice, res)
|
|
||||||
}
|
|
||||||
return mapSlice, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleSliceMapString ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 21:33 2024/5/1
|
|
||||||
func handleSliceMapString(inputValue interface{}, rule *define.FieldRule) ([]map[string]any, error) {
|
|
||||||
var (
|
|
||||||
anySlice []any
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if anySlice, err = handleSlice(inputValue, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
mapSlice := make([]map[string]any, 0)
|
|
||||||
for _, item := range anySlice {
|
|
||||||
byteData := serialize.JSON.MarshalForByte(item)
|
|
||||||
jsonRes := gjson.ParseBytes(byteData)
|
|
||||||
res := make(map[string]any)
|
|
||||||
jsonRes.ForEach(func(key, value gjson.Result) bool {
|
|
||||||
res[key.String()] = value.Value()
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
mapSlice = append(mapSlice, res)
|
|
||||||
}
|
|
||||||
return mapSlice, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleSlice 数组处理
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 21:30 2024/4/30
|
|
||||||
func handleSlice(inputValue interface{}, rule *define.FieldRule) ([]any, error) {
|
|
||||||
inputValType := reflect.TypeOf(inputValue).Kind()
|
|
||||||
if inputValType != reflect.Slice && inputValType != reflect.String {
|
|
||||||
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)
|
|
||||||
// 重置配置
|
|
||||||
if nil == rule.SliceConfig {
|
|
||||||
rule.SliceConfig = &define.SliceConfig{
|
|
||||||
Mode: consts.DataSliceModelMarshal,
|
|
||||||
DisableIgnoreEmpty: false,
|
|
||||||
DisableAutoConvert: false,
|
|
||||||
SplitChar: "",
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rule.SliceConfig.Mode = consts.DataSliceModelMarshal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
anySlice []any
|
|
||||||
)
|
|
||||||
|
|
||||||
if inputStr, ok := inputValue.(string); ok {
|
|
||||||
if anySlice, err = handleSliceString(inputStr, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err = validateSlice(anySlice, rule); nil != err {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return anySlice, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// handleSliceString ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 22:06 2024/4/30
|
|
||||||
func handleSliceString(inputStr string, rule *define.FieldRule) ([]any, error) {
|
|
||||||
if nil == rule.SliceConfig {
|
|
||||||
return nil, fmt.Errorf("%v : data type is slice, but get string", rule.Path)
|
|
||||||
}
|
|
||||||
if rule.SliceConfig.Mode == consts.DataSliceModelReal {
|
|
||||||
return nil, fmt.Errorf("%v : data type expect real slice, but get string", rule.Path)
|
|
||||||
}
|
|
||||||
if rule.SliceConfig.Mode == consts.DataSliceModelMarshal { // json序列化之后的
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
res []any
|
|
||||||
)
|
|
||||||
if err = serialize.JSON.UnmarshalWithNumber([]byte(inputStr), &res); nil != err {
|
|
||||||
return nil, fmt.Errorf("%v : data type expect marshal slice, but can not convert", rule.Path)
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
if rule.SliceConfig.Mode == consts.DataSliceModelWithSplitChar { // 指定字符串切割
|
|
||||||
strArr := strings.Split(inputStr, rule.SliceConfig.SplitChar)
|
|
||||||
anyArr := make([]any, 0)
|
|
||||||
for _, item := range strArr {
|
|
||||||
if !rule.SliceConfig.DisableIgnoreEmpty && len(item) == 0 {
|
|
||||||
// 没禁用忽略空字符串
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
anyArr = append(anyArr, item)
|
|
||||||
}
|
|
||||||
return anyArr, nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("%v : data type is slice, but rule mode [%v] is not supported", rule.Path, rule.SliceConfig.Mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// validateSlice ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 09:39 2024/5/1
|
|
||||||
func validateSlice(anySlice []any, rule *define.FieldRule) error {
|
|
||||||
|
|
||||||
// 验证
|
|
||||||
if nil == rule.ValueLimit {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if nil != rule.ValueLimit.Min && float64(len(anySlice)) < *rule.ValueLimit.Min {
|
|
||||||
return fmt.Errorf("%v : data type is slice, min length is [%v], real length is [%v]", rule.Path, *rule.ValueLimit.Min, len(anySlice))
|
|
||||||
}
|
|
||||||
|
|
||||||
if nil != rule.ValueLimit.Max && float64(len(anySlice)) > *rule.ValueLimit.Min {
|
|
||||||
return fmt.Errorf("%v : data type is slice, max length is [%v], real length is [%v]", rule.Path, *rule.ValueLimit.Max, len(anySlice))
|
|
||||||
}
|
|
||||||
|
|
||||||
enumTable := make(map[string]bool)
|
|
||||||
for _, item := range rule.ValueLimit.EnumList {
|
|
||||||
enumTable[item] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, itemVal := range anySlice {
|
|
||||||
if _, exist := enumTable[fmt.Sprintf("%v", itemVal)]; !exist {
|
|
||||||
return fmt.Errorf("%v : data type is slice, slice value [%v] is not un enum list", rule.Path, itemVal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user