From 2de1fb0c0c03c651460cb1917b1e317da6e8f5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 1 May 2024 09:40:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9slice=E7=9A=84?= =?UTF-8?q?=E9=95=BF=E5=BA=A6=E3=80=81=E6=9E=9A=E4=B8=BE=E5=80=BC=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- define/rule.go | 1 + run.go | 149 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 148 insertions(+), 2 deletions(-) diff --git a/define/rule.go b/define/rule.go index ef37090..be8e184 100644 --- a/define/rule.go +++ b/define/rule.go @@ -75,6 +75,7 @@ type MapValueLimit struct { // Date : 21:34 2024/4/30 type SliceConfig struct { Mode string `json:"slice_mode"` // REAL - 输入直接是slice MARSHAL - json序列化之后的字符串 WITH_SPLIT_CHAR - 使用指定字符串分隔 + DisableIgnoreEmpty bool `json:"disable_ignore_empty"` // 指定字符分割的时候, 忽略空字符串 DisableAutoConvert bool `json:"disable_auto_convert"` // 禁用自动格式转换, 不禁用情况下, ["1","2","3"] 可以转换成 [1,2,3] SplitChar string `json:"split_char"` // 数组转换的分隔符, 当输入模式是 WITH_SPLIT_CHAR 时生效 } diff --git a/run.go b/run.go index e92fa98..890e970 100644 --- a/run.go +++ b/run.go @@ -465,6 +465,103 @@ func validateMap(dataFieldTable map[string]string, rule *define.FieldRule) error 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 + } + + return nil, 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 + } + return nil, 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 + } + return nil, 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 + } + return nil, 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 + } + return nil, nil +} + +// handleSliceMap ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 22:30 2024/4/30 +func handleSliceMap(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 + } + return nil, nil +} + // handleSlice 数组处理 // // Author : go_developer@163.com<白茶清欢> @@ -481,6 +578,7 @@ func handleSlice(inputValue interface{}, rule *define.FieldRule) ([]any, error) if nil == rule.SliceConfig { rule.SliceConfig = &define.SliceConfig{ Mode: consts.DataSliceModelMarshal, + DisableIgnoreEmpty: false, DisableAutoConvert: false, SplitChar: "", } @@ -488,11 +586,21 @@ func handleSlice(inputValue interface{}, rule *define.FieldRule) ([]any, error) rule.SliceConfig.Mode = consts.DataSliceModelMarshal } } + var ( + err error + anySlice []any + ) + if inputStr, ok := inputValue.(string); ok { - return handleSliceString(inputStr, rule) + if anySlice, err = handleSliceString(inputStr, rule); nil != err { + return nil, err + } + } + if err = validateSlice(anySlice, rule); nil != err { + return nil, err } - return nil, fmt.Errorf("%v : data type is expect slice or string, but get %v", rule.Path, inputValType.String()) + return anySlice, nil } // handleSliceString ... @@ -521,9 +629,46 @@ func handleSliceString(inputStr string, rule *define.FieldRule) ([]any, error) { 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 +}