From cb23772664e631556b254fce7e0a77f7efff9e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Fri, 29 Nov 2024 17:55:51 +0800 Subject: [PATCH 01/14] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20todo=20=E5=BE=85?= =?UTF-8?q?=E5=A4=84=E7=90=86=E4=BA=8B=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- filter.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/filter.go b/filter.go index 4a71285..d389fd0 100644 --- a/filter.go +++ b/filter.go @@ -11,6 +11,7 @@ import ( "encoding/json" "fmt" "git.zhangdeman.cn/zhangdeman/consts" + "git.zhangdeman.cn/zhangdeman/json_filter/gjson_hack" "git.zhangdeman.cn/zhangdeman/serialize" "git.zhangdeman.cn/zhangdeman/wrapper" "reflect" @@ -58,8 +59,20 @@ func (f *filter) Deal() error { ) for _, rule := range f.filterRuleList { + if len(rule.TargetPath) == 0 { + // 未配置目标路径则, 目标路径和源路径保持一致 + rule.TargetPath = rule.SourcePath + } + if strings.Contains(rule.SourcePath, gjson_hack.ArrayIdxTpl) { + // 数组,验证数组层级是否一致 + sourceArr := strings.Split(rule.SourcePath, gjson_hack.ArrayIdxTpl) + TargetArr := strings.Split(rule.TargetPath, gjson_hack.ArrayIdxTpl) + if len(sourceArr) != len(TargetArr) { + return errors.New(rule.SourcePath + " and " + rule.TargetPath + " array deep not match") + } + } if f.IsArray(rule) { - // 对于list的处理 + // 对于list的处理, 展开层级, 并自动追加到f.filterRuleList 后面 if err = f.handleArray(rule); nil != err { return err } @@ -103,7 +116,7 @@ func (f *filter) Deal() error { // // Date : 17:48 2023/1/1 func (f *filter) IsArray(rule MapRule) bool { - return strings.Contains(rule.SourcePath, "[]") + return strings.Contains(rule.SourcePath, gjson_hack.ArrayIdxTpl) } // handleArray 处理数组(最复杂的场景) @@ -112,6 +125,7 @@ func (f *filter) IsArray(rule MapRule) bool { // // Date : 17:41 2023/1/1 func (f *filter) handleArray(rule MapRule) error { + // TODO : 对于list的处理, 展开层级, 并自动追加到f.filterRuleList 后面 var ( err error ) -- 2.36.6 From 0ca808c4fb7abd5ba7d4e156fc77151640f9922f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 30 Nov 2024 17:07:50 +0800 Subject: [PATCH 02/14] =?UTF-8?q?=E6=95=B0=E7=BB=84=E6=8C=89=E7=85=A7?= =?UTF-8?q?=E7=9C=9F=E5=AE=9E=E5=B1=82=E7=BA=A7=E5=B1=95=E5=BC=80=E5=90=8E?= =?UTF-8?q?,=20=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E6=98=A0=E5=B0=84=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gjson_hack/define.go | 3 ++- gjson_hack/path.go | 23 ++++++++++++++++++++--- gjson_hack/path_test.go | 10 +++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/gjson_hack/define.go b/gjson_hack/define.go index 855f4cf..577d477 100644 --- a/gjson_hack/define.go +++ b/gjson_hack/define.go @@ -40,5 +40,6 @@ const ( // // Date : 15:46 2024/11/29 type ExpendArrayResult struct { - PathList []string `json:"path_list"` // 路径列表 + PathList []string `json:"path_list"` // 路径列表 + PathMap map[string]string `json:"path_map"` // 数据源路径 => 目标路径的处理 } diff --git a/gjson_hack/path.go b/gjson_hack/path.go index 3f06cee..2a4bc38 100644 --- a/gjson_hack/path.go +++ b/gjson_hack/path.go @@ -10,8 +10,9 @@ package gjson_hack import ( "errors" "fmt" - "github.com/tidwall/gjson" "strings" + + "github.com/tidwall/gjson" ) // newDefaultPathOption 默认路径展开选项 @@ -131,22 +132,37 @@ func doExpandPath(gjsonResult gjson.Result, rootPath string, hasChildren bool, p // Author : go_developer@163.com<白茶清欢> // // Date : 11:13 2024/11/29 -func ExpandArrayPath(jsonStr string, pathConfig string, expendArrayResult *ExpendArrayResult) error { +func ExpandArrayPath(jsonStr string, pathConfig string, mapConfig string, expendArrayResult *ExpendArrayResult) error { if nil == expendArrayResult { return errors.New("expendArrayResult can not be nil") } if nil == expendArrayResult.PathList { expendArrayResult.PathList = make([]string, 0) } + if nil == expendArrayResult.PathMap { + expendArrayResult.PathMap = make(map[string]string) + } + if len(mapConfig) == 0 { + mapConfig = pathConfig + } if !strings.Contains(pathConfig, ArrayIdxTpl) { // 不是数组模板配置, 无需展开 expendArrayResult.PathList = append(expendArrayResult.PathList, pathConfig) + expendArrayResult.PathMap[pathConfig] = mapConfig return nil } + mapConfigArr := strings.Split(pathConfig, ArrayIdxTpl) + mapConfigArr[0] = strings.TrimSuffix(mapConfigArr[0], ".") + mapSuffixPathTpl := strings.TrimPrefix(strings.Join(mapConfigArr[1:], ArrayIdxTpl), ".") pathConfigArr := strings.Split(pathConfig, ArrayIdxTpl) pathConfigArr[0] = strings.TrimSuffix(pathConfigArr[0], ".") suffixPathTpl := strings.TrimPrefix(strings.Join(pathConfigArr[1:], ArrayIdxTpl), ".") + + if len(mapConfigArr) != len(pathConfigArr) { + return errors.New("mapConfig depth not equal pathConfig deep") + } + valueResult := gjson.Parse(jsonStr).Get(pathConfigArr[0]) if !valueResult.Exists() { // 路径不存在, 无需设置具体值 @@ -155,12 +171,13 @@ func ExpandArrayPath(jsonStr string, pathConfig string, expendArrayResult *Expen if !valueResult.IsArray() { // 不是数组,不要继续再向后展开了 expendArrayResult.PathList = append(expendArrayResult.PathList, pathConfigArr[0]) + expendArrayResult.PathMap[pathConfigArr[0]] = mapConfigArr[0] return nil } // 继续展开子项 for idx, _ := range valueResult.Array() { idxStr := fmt.Sprintf("%v", idx) - if err := ExpandArrayPath(jsonStr, pathConfigArr[0]+"."+idxStr+"."+suffixPathTpl, expendArrayResult); nil != err { + if err := ExpandArrayPath(jsonStr, pathConfigArr[0]+"."+idxStr+"."+suffixPathTpl, mapConfigArr[0]+"."+idxStr+"."+mapSuffixPathTpl, expendArrayResult); nil != err { return err } } diff --git a/gjson_hack/path_test.go b/gjson_hack/path_test.go index 6b2409b..16a6211 100644 --- a/gjson_hack/path_test.go +++ b/gjson_hack/path_test.go @@ -10,8 +10,9 @@ package gjson_hack import ( "encoding/json" "fmt" - "github.com/tidwall/gjson" "testing" + + "github.com/tidwall/gjson" ) func TestPath(t *testing.T) { @@ -163,7 +164,10 @@ func TestExpandArrayPath(t *testing.T) { byteData, _ := json.Marshal(mapData) jsonStr := string(byteData) // fmt.Println(jsonStr) - var pathExpendRes = &ExpendArrayResult{PathList: nil} - ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.age", pathExpendRes) + var pathExpendRes = &ExpendArrayResult{ + PathList: nil, + PathMap: nil, + } + ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.age", "", pathExpendRes) fmt.Println(pathExpendRes) } -- 2.36.6 From c1775552cc7dfbea9d0633cc03fc13b06881d4ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 30 Nov 2024 17:22:16 +0800 Subject: [PATCH 03/14] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gjson_hack/path_test.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/gjson_hack/path_test.go b/gjson_hack/path_test.go index 16a6211..8bd5f64 100644 --- a/gjson_hack/path_test.go +++ b/gjson_hack/path_test.go @@ -12,6 +12,8 @@ import ( "fmt" "testing" + "github.com/tidwall/sjson" + "github.com/tidwall/gjson" ) @@ -168,6 +170,12 @@ func TestExpandArrayPath(t *testing.T) { PathList: nil, PathMap: nil, } - ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.age", "", pathExpendRes) - fmt.Println(pathExpendRes) + ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.age", "a.{{idx}}.{{idx}}.b", pathExpendRes) + ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.name", "a.{{idx}}.{{idx}}.c", pathExpendRes) + ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.sex", "a.{{idx}}.{{idx}}.c", pathExpendRes) + res := "" + for _, item := range pathExpendRes.PathList { + res, _ = sjson.Set(res, pathExpendRes.PathMap[item], gjson.Get(jsonStr, item).Value()) + } + fmt.Println(res) } -- 2.36.6 From ce1e7fe9dadbd90fcf5b565cc69d5e600be20c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 30 Nov 2024 17:31:55 +0800 Subject: [PATCH 04/14] =?UTF-8?q?=E4=BF=AE=E5=A4=8DmapConfig=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gjson_hack/path.go | 2 +- gjson_hack/path_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gjson_hack/path.go b/gjson_hack/path.go index 2a4bc38..57bf1ea 100644 --- a/gjson_hack/path.go +++ b/gjson_hack/path.go @@ -151,7 +151,7 @@ func ExpandArrayPath(jsonStr string, pathConfig string, mapConfig string, expend expendArrayResult.PathMap[pathConfig] = mapConfig return nil } - mapConfigArr := strings.Split(pathConfig, ArrayIdxTpl) + mapConfigArr := strings.Split(mapConfig, ArrayIdxTpl) mapConfigArr[0] = strings.TrimSuffix(mapConfigArr[0], ".") mapSuffixPathTpl := strings.TrimPrefix(strings.Join(mapConfigArr[1:], ArrayIdxTpl), ".") diff --git a/gjson_hack/path_test.go b/gjson_hack/path_test.go index 8bd5f64..e607098 100644 --- a/gjson_hack/path_test.go +++ b/gjson_hack/path_test.go @@ -171,8 +171,8 @@ func TestExpandArrayPath(t *testing.T) { PathMap: nil, } ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.age", "a.{{idx}}.{{idx}}.b", pathExpendRes) - ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.name", "a.{{idx}}.{{idx}}.c", pathExpendRes) - ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.sex", "a.{{idx}}.{{idx}}.c", pathExpendRes) + ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.name", "e.{{idx}}.{{idx}}.c", pathExpendRes) + ExpandArrayPath(jsonStr, "user_list.{{idx}}.{{idx}}.sex", "f.{{idx}}.{{idx}}.c", pathExpendRes) res := "" for _, item := range pathExpendRes.PathList { res, _ = sjson.Set(res, pathExpendRes.PathMap[item], gjson.Get(jsonStr, item).Value()) -- 2.36.6 From 68d3d7606292b6e85ad3c1ad879b62f965312d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 30 Nov 2024 19:07:55 +0800 Subject: [PATCH 05/14] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- filter.go | 120 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/filter.go b/filter.go index d389fd0..f8c92f1 100644 --- a/filter.go +++ b/filter.go @@ -10,12 +10,13 @@ package filter import ( "encoding/json" "fmt" + "reflect" + "strings" + "git.zhangdeman.cn/zhangdeman/consts" "git.zhangdeman.cn/zhangdeman/json_filter/gjson_hack" "git.zhangdeman.cn/zhangdeman/serialize" "git.zhangdeman.cn/zhangdeman/wrapper" - "reflect" - "strings" "github.com/tidwall/gjson" "github.com/tidwall/sjson" @@ -54,8 +55,7 @@ type filter struct { // Date : 11:59 2022/7/4 func (f *filter) Deal() error { var ( - err error - formatVal any + err error ) for _, rule := range f.filterRuleList { @@ -63,14 +63,6 @@ func (f *filter) Deal() error { // 未配置目标路径则, 目标路径和源路径保持一致 rule.TargetPath = rule.SourcePath } - if strings.Contains(rule.SourcePath, gjson_hack.ArrayIdxTpl) { - // 数组,验证数组层级是否一致 - sourceArr := strings.Split(rule.SourcePath, gjson_hack.ArrayIdxTpl) - TargetArr := strings.Split(rule.TargetPath, gjson_hack.ArrayIdxTpl) - if len(sourceArr) != len(TargetArr) { - return errors.New(rule.SourcePath + " and " + rule.TargetPath + " array deep not match") - } - } if f.IsArray(rule) { // 对于list的处理, 展开层级, 并自动追加到f.filterRuleList 后面 if err = f.handleArray(rule); nil != err { @@ -78,32 +70,7 @@ func (f *filter) Deal() error { } continue } - sourceResult := gjson.Get(f.sourceData, rule.SourcePath) - if formatVal, err = f.getValue(rule.DataType, sourceResult, rule.DefaultValue); nil != err { - return fmt.Errorf("%s = %v can not convert to %s : %s", rule.SourcePath, sourceResult.Value(), rule.DataType, err.Error()) - } - if reflect.TypeOf(formatVal).Kind() == reflect.Map { - // 获取的数据是map类型, 处理数据覆盖 - // eg : 配置如下两个规则 process.id(string) 、process(map[string]any) - // 若输入数据的process.id为int类型, 则格式化后的process.id必为 string, 应为 process.id 规则的控制更精细 - gjsonVal := gjson.Get(f.formatResult, rule.TargetPath) - if gjsonVal.Exists() && gjsonVal.IsObject() { - var ( - existRes = map[string]any{} - formatRes = map[string]any{} - ) - // 已存在, 且是对象 - _ = serialize.JSON.UnmarshalWithNumber([]byte(gjsonVal.String()), &existRes) - if err = serialize.JSON.Transition(formatVal, &formatRes); nil != err { - return errors.New("conflict data path config deal fail : " + err.Error()) - } - for k, v := range existRes { - formatRes[k] = v - } - formatVal = formatRes // 重新赋值 formatVal - } - } - if f.formatResult, err = sjson.Set(f.formatResult, rule.TargetPath, formatVal); nil != err { + if err = f.setResult(rule); nil != err { return err } } @@ -125,34 +92,71 @@ func (f *filter) IsArray(rule MapRule) bool { // // Date : 17:41 2023/1/1 func (f *filter) handleArray(rule MapRule) error { - // TODO : 对于list的处理, 展开层级, 并自动追加到f.filterRuleList 后面 + // 对于list的处理, 展开层级, 并自动追加到f.filterRuleList 后面 var ( err error ) - sourcePathArray := strings.Split(rule.SourcePath, "[]") - for idx, item := range sourcePathArray { - sourcePathArray[idx] = strings.Trim(item, ".") + expendRes := &gjson_hack.ExpendArrayResult{ + PathList: make([]string, 0), + PathMap: map[string]string{}, } - mapPathArray := strings.Split(strings.TrimRight(rule.TargetPath, ".[]"), "[]") - for idx, item := range mapPathArray { - mapPathArray[idx] = strings.Trim(item, ".") + if err = gjson_hack.ExpandArrayPath(f.sourceData, rule.SourcePath, rule.TargetPath, expendRes); nil != err { + return err } - if len(sourcePathArray) != len(mapPathArray) { - if len(mapPathArray) != 1 { - return errors.New("map rule is invalid") - } - // 提取某一个list下的字段, 组成一个list - res := make([]string, 0) - if len(sourcePathArray[0]) == 0 { - f.getAllFinalData(&res, gjson.Parse(f.sourceData).Array(), sourcePathArray[1:]) - } else { - f.getAllFinalData(&res, gjson.Get(f.sourceData, sourcePathArray[0]).Array(), sourcePathArray[1:]) - } - if f.formatResult, err = sjson.Set(f.formatResult, mapPathArray[0], res); nil != err { + for _, itemPath := range expendRes.PathList { + if err = f.setResult(MapRule{ + SourcePath: itemPath, + TargetPath: expendRes.PathMap[itemPath], + Required: rule.Required, + DataType: rule.DataType, + DefaultValue: rule.DefaultValue, + }); nil != err { return err } - return nil + } + + return nil +} + +// setResult 设置结果 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 19:03 2024/11/30 +func (f *filter) setResult(rule MapRule) error { + var ( + err error + formatVal any + ) + + sourceResult := gjson.Get(f.sourceData, rule.SourcePath) + if formatVal, err = f.getValue(rule.DataType, sourceResult, rule.DefaultValue); nil != err { + return fmt.Errorf("%s = %v can not convert to %s : %s", rule.SourcePath, sourceResult.Value(), rule.DataType, err.Error()) + } + if reflect.TypeOf(formatVal).Kind() == reflect.Map { + // 获取的数据是map类型, 处理数据覆盖 + // eg : 配置如下两个规则 process.id(string) 、process(map[string]any) + // 若输入数据的process.id为int类型, 则格式化后的process.id必为 string, 应为 process.id 规则的控制更精细 + gjsonVal := gjson.Get(f.formatResult, rule.TargetPath) + if gjsonVal.Exists() && gjsonVal.IsObject() { + var ( + existRes = map[string]any{} + formatRes = map[string]any{} + ) + // 已存在, 且是对象 + _ = serialize.JSON.UnmarshalWithNumber([]byte(gjsonVal.String()), &existRes) + if err = serialize.JSON.Transition(formatVal, &formatRes); nil != err { + return errors.New("conflict data path config deal fail : " + err.Error()) + } + for k, v := range existRes { + formatRes[k] = v + } + formatVal = formatRes // 重新赋值 formatVal + } + } + if f.formatResult, err = sjson.Set(f.formatResult, rule.TargetPath, formatVal); nil != err { + return err } return nil } -- 2.36.6 From 8cca556d6f79893d7e7de1d70569b68e912fe3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 30 Nov 2024 21:53:28 +0800 Subject: [PATCH 06/14] =?UTF-8?q?=E4=BC=98=E5=8C=96error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- error.go | 14 ++++++++++++++ filter.go | 19 ++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 error.go diff --git a/error.go b/error.go new file mode 100644 index 0000000..6896b95 --- /dev/null +++ b/error.go @@ -0,0 +1,14 @@ +// Package filter ... +// +// Description : filter ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2024-11-30 19:14 +package filter + +import "errors" + +var ( + ErrDataIsNotObject = errors.New("data is not an object") +) diff --git a/filter.go b/filter.go index f8c92f1..3e59717 100644 --- a/filter.go +++ b/filter.go @@ -242,6 +242,7 @@ func (f *filter) getValue(dataType consts.DataType, sourceValue gjson.Result, de return strVal.Value(), nil case consts.DataTypeAny: if sourceValue.Exists() { + // TODO : 可能存在精度丢失 return sourceValue.Value(), nil } return defaultValue, nil @@ -251,7 +252,7 @@ func (f *filter) getValue(dataType consts.DataType, sourceValue gjson.Result, de return sliceVal.Value, sliceVal.Err case consts.DataTypeSliceInt, consts.DataTypeSliceIntWithChar: // 任意类型的list - if strings.HasPrefix(strVal.Value(), "[") && strings.HasPrefix(strVal.Value(), "]") { + if strings.HasPrefix(strVal.Value(), "[") && strings.HasSuffix(strVal.Value(), "]") { // 序列化之后的数组 sliceVal := strVal.ToInt64Slice() return sliceVal.Value, sliceVal.Err @@ -310,54 +311,54 @@ func (f *filter) getValue(dataType consts.DataType, sourceValue gjson.Result, de return res, err case consts.DataTypeMapStrInt: if !sourceValue.IsObject() { - return nil, errors.New("data type is not object") + return nil, ErrDataIsNotObject } var res map[string]int64 err := strVal.ToStruct(&res) return res, err case consts.DataTypeMapStrUint: if !sourceValue.IsObject() { - return nil, errors.New("data type is not object") + return nil, ErrDataIsNotObject } var res map[string]uint64 err := strVal.ToStruct(&res) return res, err case consts.DataTypeMapStrFloat: if !sourceValue.IsObject() { - return nil, errors.New("data type is not object") + return nil, ErrDataIsNotObject } var res map[string]float64 err := strVal.ToStruct(&res) return res, err case consts.DataTypeMapStrBool: if !sourceValue.IsObject() { - return nil, errors.New("data type is not object") + return nil, ErrDataIsNotObject } var res map[string]bool err := strVal.ToStruct(&res) return res, err case consts.DataTypeMapStrAny: if !sourceValue.IsObject() { - return nil, errors.New("data type is not object") + return nil, ErrDataIsNotObject } var res map[string]any err := strVal.ToStruct(&res) return res, err case consts.DataTypeMapStrStr: if !sourceValue.IsObject() { - return nil, errors.New("data type is not object") + return nil, ErrDataIsNotObject } var res map[string]string err := strVal.ToStruct(&res) return res, err case consts.DataTypeMapStrSlice: if !sourceValue.IsObject() { - return nil, errors.New("data type is not object") + return nil, ErrDataIsNotObject } var res map[string][]any err := strVal.ToStruct(&res) return res, err default: - return nil, errors.New(dataType.String() + " is not support!") + return nil, errors.New("`" + dataType.String() + "` is not support!") } } -- 2.36.6 From c10486b4038fe152db19f355c3c25ad5dcebf3b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 30 Nov 2024 22:04:29 +0800 Subject: [PATCH 07/14] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=BD=9C=E5=9C=A8?= =?UTF-8?q?=E7=9A=84=E4=B8=A2=E5=A4=B1=E7=B2=BE=E5=BA=A6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- filter.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/filter.go b/filter.go index 3e59717..b5b1767 100644 --- a/filter.go +++ b/filter.go @@ -13,6 +13,8 @@ import ( "reflect" "strings" + "git.zhangdeman.cn/zhangdeman/util" + "git.zhangdeman.cn/zhangdeman/consts" "git.zhangdeman.cn/zhangdeman/json_filter/gjson_hack" "git.zhangdeman.cn/zhangdeman/serialize" @@ -242,7 +244,15 @@ func (f *filter) getValue(dataType consts.DataType, sourceValue gjson.Result, de return strVal.Value(), nil case consts.DataTypeAny: if sourceValue.Exists() { - // TODO : 可能存在精度丢失 + // 可能存在精度丢失, 原因 : gjson.Value 内置的转换, int64 超过一定大小会存在丢失精度问题 + if sourceValue.Num > 0 { + // 说明是数字 + var res float64 + if err := util.ConvertAssign(&res, sourceValue.String()); nil != err { + return nil, err + } + return res, nil + } return sourceValue.Value(), nil } return defaultValue, nil -- 2.36.6 From d466b7526de0db32babe8fb086c4046d4d191848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sun, 1 Dec 2024 15:10:48 +0800 Subject: [PATCH 08/14] =?UTF-8?q?=E4=BC=98=E5=8C=96slice=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- error.go => gjson_hack/error.go | 5 +- gjson_hack/precision.go | 286 ++++++++++++++++++++++++++++++++ 2 files changed, 289 insertions(+), 2 deletions(-) rename error.go => gjson_hack/error.go (65%) diff --git a/error.go b/gjson_hack/error.go similarity index 65% rename from error.go rename to gjson_hack/error.go index 6896b95..5e65ef8 100644 --- a/error.go +++ b/gjson_hack/error.go @@ -1,14 +1,15 @@ -// Package filter ... +// Package gjson_hack ... // // Description : filter ... // // Author : go_developer@163.com<白茶清欢> // // Date : 2024-11-30 19:14 -package filter +package gjson_hack import "errors" var ( ErrDataIsNotObject = errors.New("data is not an object") + ErrDataIsNotArray = errors.New("data is not an array") ) diff --git a/gjson_hack/precision.go b/gjson_hack/precision.go index 1877737..2baec52 100644 --- a/gjson_hack/precision.go +++ b/gjson_hack/precision.go @@ -9,8 +9,11 @@ package gjson_hack import ( "errors" + "git.zhangdeman.cn/zhangdeman/consts" "git.zhangdeman.cn/zhangdeman/util" + "git.zhangdeman.cn/zhangdeman/wrapper" "github.com/tidwall/gjson" + "strings" ) // Number 结果转换为数字(int64 / uint64 / float64) @@ -69,3 +72,286 @@ func Float64(gjsonResult gjson.Result) (float64, error) { } return float64Result, nil } + +// String 获取字符串值 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 10:55 2024/12/1 +func String(sourceValue gjson.Result, defaultValue string) string { + sourceValueStr := defaultValue + if sourceValue.Exists() { + str := sourceValue.String() + if len(str) > 0 { + sourceValueStr = str + } + } + return sourceValueStr +} + +// Any 获取任意类型的值 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 11:00 2024/12/1 +func Any(sourceValue gjson.Result) (any, error) { + if !sourceValue.Exists() { + return nil, nil + } + // 可能存在精度丢失, 原因 : gjson.Value 内置的转换, int64 超过一定大小会存在丢失精度问题 + if sourceValue.Num > 0 || sourceValue.Num < 0 { + // 说明是数字 + var res float64 + if err := util.ConvertAssign(&res, sourceValue.String()); nil != err { + return nil, err + } + return res, nil + } + if sourceValue.IsObject() { + // 对象不管什么类型的key, 统一转成 map[string]any + res := make(map[string]any) + sourceValue.ForEach(func(k, v gjson.Result) bool { + res[k.String()] = v + return true + }) + } + return sourceValue.Value(), nil + +} + +// getRealDataType ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 14:28 2024/12/1 +func getRealDataType(dataType consts.DataType, sourceValue gjson.Result) consts.DataType { + if dataType == consts.DataTypeAny { + if sourceValue.IsObject() { + dataType = consts.DataTypeMapAnyAny + } else if sourceValue.IsArray() { + dataType = consts.DataTypeSliceAny + } else { + if sourceValue.Num != 0 { + dataType = consts.DataTypeFloat + } + } + } + return dataType +} + +// SliceInt 获取int list +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 14:43 2024/12/1 +func SliceInt(gjsonResult gjson.Result) ([]int64, error) { + if gjsonResult.Value() == nil { + return nil, nil + } + + strVal := strings.TrimSpace(gjsonResult.String()) + // 任意类型的list + if strings.HasPrefix(strVal, "[") && strings.HasSuffix(strVal, "]") { + // 序列化之后的数组 + sliceVal := wrapper.String(strVal).ToInt64Slice() + return sliceVal.Value, sliceVal.Err + } + // 分隔的数组 + sliceVal := wrapper.String(strVal).ToInt64Slice(",") + return sliceVal.Value, sliceVal.Err +} + +// SliceUint ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 14:58 2024/12/1 +func SliceUint(gjsonResult gjson.Result) ([]uint64, error) { + if gjsonResult.Value() == nil { + return nil, nil + } + + strVal := strings.TrimSpace(gjsonResult.String()) + // 任意类型的list + if strings.HasPrefix(strVal, "[") && strings.HasSuffix(strVal, "]") { + // 序列化之后的数组 + sliceVal := wrapper.String(strVal).ToUint64Slice() + return sliceVal.Value, sliceVal.Err + } + // 分隔的数组 + sliceVal := wrapper.String(strVal).ToUint64Slice(",") + return sliceVal.Value, sliceVal.Err +} + +// SliceFloat ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 14:59 2024/12/1 +func SliceFloat(gjsonResult gjson.Result) ([]float64, error) { + if gjsonResult.Value() == nil { + return nil, nil + } + + strVal := strings.TrimSpace(gjsonResult.String()) + // 任意类型的list + if strings.HasPrefix(strVal, "[") && strings.HasSuffix(strVal, "]") { + // 序列化之后的数组 + sliceVal := wrapper.String(strVal).ToFloat64Slice() + return sliceVal.Value, sliceVal.Err + } + // 分隔的数组 + sliceVal := wrapper.String(strVal).ToFloat64Slice(",") + return sliceVal.Value, sliceVal.Err +} + +// SliceBool ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 15:00 2024/12/1 +func SliceBool(gjsonResult gjson.Result) ([]bool, error) { + if gjsonResult.Value() == nil { + return nil, nil + } + + strVal := strings.TrimSpace(gjsonResult.String()) + // 任意类型的list + if strings.HasPrefix(strVal, "[") && strings.HasSuffix(strVal, "]") { + // 序列化之后的数组 + sliceVal := wrapper.String(strVal).ToBoolSlice() + return sliceVal.Value, sliceVal.Err + } + // 分隔的数组 + sliceVal := wrapper.String(strVal).ToBoolSlice(",") + return sliceVal.Value, sliceVal.Err +} + +// SliceString ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 15:03 2024/12/1 +func SliceString(gjsonResult gjson.Result) ([]string, error) { + if gjsonResult.Value() == nil { + return nil, nil + } + + strVal := strings.TrimSpace(gjsonResult.String()) + // 任意类型的list + if strings.HasPrefix(strVal, "[") && strings.HasSuffix(strVal, "]") { + // 序列化之后的数组 + sliceVal := wrapper.String(strVal).ToStringSlice() + return sliceVal.Value, sliceVal.Err + } + // 分隔的数组 + sliceVal := wrapper.String(strVal).ToStringSlice(",") + return sliceVal.Value, sliceVal.Err +} + +// Value 获取指定的值 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 10:52 2024/12/1 +func Value(dataType consts.DataType, sourceValue gjson.Result, defaultValue any) (any, error) { + if !sourceValue.Exists() { + return defaultValue, nil + } + dataType = getRealDataType(dataType, sourceValue) + strVal := wrapper.String(sourceValue.String()) + switch dataType { + case consts.DataTypeInt: + return Int(sourceValue) + case consts.DataTypeUint: + return Uint(sourceValue) + case consts.DataTypeFloat: + return Float64(sourceValue) + case consts.DataTypeBool: + boolVal := strVal.ToBool() + return boolVal.Value, boolVal.Err + case consts.DataTypeString: + return sourceValue.String(), nil + case consts.DataTypeAny: + return sourceValue.Value(), nil + case consts.DataTypeSliceAny: + // 任意类型的list + sliceVal := strVal.ToAnySlice() + return sliceVal.Value, sliceVal.Err + case consts.DataTypeSliceInt, consts.DataTypeSliceIntWithChar: + // 任意类型的list + return SliceInt(sourceValue) + case consts.DataTypeSliceUint, consts.DataTypeSliceUintWithChar: + // 任意类型的list + return SliceUint(sourceValue) + case consts.DataTypeSliceFloat, consts.DataTypeSliceFloatWithChar: + // 任意类型的list + return SliceFloat(sourceValue) + case consts.DataTypeSliceBool, consts.DataTypeSliceBoolWithChar: + // 任意类型的list + return SliceBool(sourceValue) + case consts.DataTypeSliceString, consts.DataTypeSliceStringWithChar: + // 任意类型的list + return SliceString(sourceValue) + case consts.DataTypeSliceSlice, consts.DataTypeMapAnyAny: + return nil, errors.New(consts.DataTypeSliceSlice.String() + " : data type is not support") + case consts.DataTypeSliceMapStringAny: + if !sourceValue.IsArray() { + return nil, ErrDataIsNotArray + } + var res []map[string]any + err := strVal.ToStruct(&res) + return res, err + case consts.DataTypeMapStrInt: + if !sourceValue.IsObject() { + return nil, ErrDataIsNotObject + } + var res map[string]int64 + err := strVal.ToStruct(&res) + return res, err + case consts.DataTypeMapStrUint: + if !sourceValue.IsObject() { + return nil, ErrDataIsNotObject + } + var res map[string]uint64 + err := strVal.ToStruct(&res) + return res, err + case consts.DataTypeMapStrFloat: + if !sourceValue.IsObject() { + return nil, ErrDataIsNotObject + } + var res map[string]float64 + err := strVal.ToStruct(&res) + return res, err + case consts.DataTypeMapStrBool: + if !sourceValue.IsObject() { + return nil, ErrDataIsNotObject + } + var res map[string]bool + err := strVal.ToStruct(&res) + return res, err + case consts.DataTypeMapStrAny: + if !sourceValue.IsObject() { + return nil, ErrDataIsNotObject + } + var res map[string]any + err := strVal.ToStruct(&res) + return res, err + case consts.DataTypeMapStrStr: + if !sourceValue.IsObject() { + return nil, ErrDataIsNotObject + } + var res map[string]string + err := strVal.ToStruct(&res) + return res, err + case consts.DataTypeMapStrSlice: + if !sourceValue.IsObject() { + return nil, ErrDataIsNotObject + } + var res map[string][]any + err := strVal.ToStruct(&res) + return res, err + default: + return nil, errors.New("`" + dataType.String() + "` is not support!") + } +} -- 2.36.6 From 5ae18410238bebed855f4bbc2a08f3875ea19054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sun, 1 Dec 2024 15:46:16 +0800 Subject: [PATCH 09/14] =?UTF-8?q?=E4=BC=98=E5=8C=96[]map[string]any?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gjson_hack/precision.go | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/gjson_hack/precision.go b/gjson_hack/precision.go index 2baec52..188300e 100644 --- a/gjson_hack/precision.go +++ b/gjson_hack/precision.go @@ -10,6 +10,7 @@ package gjson_hack import ( "errors" "git.zhangdeman.cn/zhangdeman/consts" + "git.zhangdeman.cn/zhangdeman/serialize" "git.zhangdeman.cn/zhangdeman/util" "git.zhangdeman.cn/zhangdeman/wrapper" "github.com/tidwall/gjson" @@ -249,6 +250,28 @@ func SliceString(gjsonResult gjson.Result) ([]string, error) { return sliceVal.Value, sliceVal.Err } +// SliceMapStringAny ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 15:41 2024/12/1 +func SliceMapStringAny(gjsonResult gjson.Result) ([]map[string]any, error) { + if gjsonResult.Value() == nil { + return nil, nil + } + + strVal := strings.TrimSpace(gjsonResult.String()) + // 任意类型的list + if !strings.HasPrefix(strVal, "[") || !strings.HasSuffix(strVal, "]") { + return nil, ErrDataIsNotArray + } + var res []map[string]any + if err := serialize.JSON.UnmarshalWithNumber([]byte(strVal), &res); nil != err { + return nil, err + } + return res, nil +} + // Value 获取指定的值 // // Author : go_developer@163.com<白茶清欢> @@ -296,12 +319,7 @@ func Value(dataType consts.DataType, sourceValue gjson.Result, defaultValue any) case consts.DataTypeSliceSlice, consts.DataTypeMapAnyAny: return nil, errors.New(consts.DataTypeSliceSlice.String() + " : data type is not support") case consts.DataTypeSliceMapStringAny: - if !sourceValue.IsArray() { - return nil, ErrDataIsNotArray - } - var res []map[string]any - err := strVal.ToStruct(&res) - return res, err + return SliceMapStringAny(sourceValue) case consts.DataTypeMapStrInt: if !sourceValue.IsObject() { return nil, ErrDataIsNotObject -- 2.36.6 From d25e579ecf3bd35bd8c51cb8e888da0030607b5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sun, 1 Dec 2024 18:14:34 +0800 Subject: [PATCH 10/14] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=B0=86=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E5=8C=96=E4=B9=8B=E5=90=8E=E7=9A=84=E6=95=B0=E7=BB=84?= =?UTF-8?q?=E3=80=81=E5=AF=B9=E8=B1=A1=E5=AD=97=E7=AC=A6=E4=B8=B2=E8=BD=AC?= =?UTF-8?q?=E5=9B=9E=E6=95=B0=E7=BB=84=E3=80=81=E5=AF=B9=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gjson_hack/path.go | 59 +++++++++++++++++++++++++++++++++++++++++ gjson_hack/path_test.go | 2 +- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/gjson_hack/path.go b/gjson_hack/path.go index 57bf1ea..2e7995a 100644 --- a/gjson_hack/path.go +++ b/gjson_hack/path.go @@ -183,3 +183,62 @@ func ExpandArrayPath(jsonStr string, pathConfig string, mapConfig string, expend } return nil } + +// IsObject 判断是否是对象, 兼容序列化之后的对象 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:04 2024/12/1 +func IsObject(gjsonResult gjson.Result) bool { + return gjsonResult.IsObject() || gjson.Parse(gjsonResult.String()).IsObject() +} + +// IsArray 判断是否为数组 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:05 2024/12/1 +func IsArray(gjsonResult gjson.Result) bool { + return gjsonResult.IsArray() || gjson.Parse(gjsonResult.String()).IsArray() +} + +// Object 兼容序列化之后的对象 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:09 2024/12/1 +func Object(gjsonResult gjson.Result) gjson.Result { + res := gjson.Parse(gjsonResult.String()) + if res.IsObject() { + return res + } + return gjsonResult +} + +// Array ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:09 2024/12/1 +func Array(gjsonResult gjson.Result) gjson.Result { + res := gjson.Parse(gjsonResult.String()) + if res.IsArray() { + return res + } + return gjsonResult +} + +// Result ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:12 2024/12/1 +func Result(gjsonResult gjson.Result) gjson.Result { + if IsObject(gjsonResult) { + return gjsonResult + } + if IsArray(gjsonResult) { + return Array(gjsonResult) + } + return gjsonResult +} diff --git a/gjson_hack/path_test.go b/gjson_hack/path_test.go index e607098..1848b11 100644 --- a/gjson_hack/path_test.go +++ b/gjson_hack/path_test.go @@ -165,7 +165,7 @@ func TestExpandArrayPath(t *testing.T) { } byteData, _ := json.Marshal(mapData) jsonStr := string(byteData) - // fmt.Println(jsonStr) + var pathExpendRes = &ExpendArrayResult{ PathList: nil, PathMap: nil, -- 2.36.6 From 4a318f3638dabb8e94533f1122844406eba13b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sun, 1 Dec 2024 18:25:27 +0800 Subject: [PATCH 11/14] =?UTF-8?q?=E5=A2=9E=E5=8A=A0ma[any]any/sliceSlice?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gjson_hack/precision.go | 80 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/gjson_hack/precision.go b/gjson_hack/precision.go index 188300e..662fc35 100644 --- a/gjson_hack/precision.go +++ b/gjson_hack/precision.go @@ -90,6 +90,23 @@ func String(sourceValue gjson.Result, defaultValue string) string { return sourceValueStr } +// MapAnyAny ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:48 2024/12/1 +func MapAnyAny(sourceValue gjson.Result) (map[string]any, error) { + if !sourceValue.IsObject() { + return nil, ErrDataIsNotObject + } + res := make(map[string]any) + sourceValue.ForEach(func(key, value gjson.Result) bool { + res[key.String()] = value + return true + }) + return res, nil +} + // Any 获取任意类型的值 // // Author : go_developer@163.com<白茶清欢> @@ -109,12 +126,10 @@ func Any(sourceValue gjson.Result) (any, error) { return res, nil } if sourceValue.IsObject() { - // 对象不管什么类型的key, 统一转成 map[string]any - res := make(map[string]any) - sourceValue.ForEach(func(k, v gjson.Result) bool { - res[k.String()] = v - return true - }) + return MapAnyAny(sourceValue) + } + if sourceValue.IsArray() { + return SliceAny(sourceValue) } return sourceValue.Value(), nil @@ -140,6 +155,28 @@ func getRealDataType(dataType consts.DataType, sourceValue gjson.Result) consts. return dataType } +// SliceAny ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:53 2024/12/1 +func SliceAny(gjsonResult gjson.Result) ([]any, error) { + if gjsonResult.Value() == nil { + return nil, nil + } + + strVal := strings.TrimSpace(gjsonResult.String()) + // 任意类型的list + if strings.HasPrefix(strVal, "[") && strings.HasSuffix(strVal, "]") { + // 序列化之后的数组 + sliceVal := wrapper.String(strVal).ToAnySlice() + return sliceVal.Value, sliceVal.Err + } + // 分隔的数组 + sliceVal := wrapper.String(strVal).ToAnySlice(",") + return sliceVal.Value, sliceVal.Err +} + // SliceInt 获取int list // // Author : go_developer@163.com<白茶清欢> @@ -149,7 +186,6 @@ func SliceInt(gjsonResult gjson.Result) ([]int64, error) { if gjsonResult.Value() == nil { return nil, nil } - strVal := strings.TrimSpace(gjsonResult.String()) // 任意类型的list if strings.HasPrefix(strVal, "[") && strings.HasSuffix(strVal, "]") { @@ -272,6 +308,28 @@ func SliceMapStringAny(gjsonResult gjson.Result) ([]map[string]any, error) { return res, nil } +// SliceSlice ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:44 2024/12/1 +func SliceSlice(gjsonResult gjson.Result) ([][]any, error) { + if gjsonResult.Value() == nil { + return nil, nil + } + + strVal := strings.TrimSpace(gjsonResult.String()) + // 任意类型的list + if !strings.HasPrefix(strVal, "[") || !strings.HasSuffix(strVal, "]") { + return nil, ErrDataIsNotArray + } + var res [][]any + if err := serialize.JSON.UnmarshalWithNumber([]byte(strVal), &res); nil != err { + return nil, err + } + return res, nil +} + // Value 获取指定的值 // // Author : go_developer@163.com<白茶清欢> @@ -281,6 +339,8 @@ func Value(dataType consts.DataType, sourceValue gjson.Result, defaultValue any) if !sourceValue.Exists() { return defaultValue, nil } + // 归一化处理对象、数组等 + sourceValue = Result(sourceValue) dataType = getRealDataType(dataType, sourceValue) strVal := wrapper.String(sourceValue.String()) switch dataType { @@ -316,8 +376,10 @@ func Value(dataType consts.DataType, sourceValue gjson.Result, defaultValue any) case consts.DataTypeSliceString, consts.DataTypeSliceStringWithChar: // 任意类型的list return SliceString(sourceValue) - case consts.DataTypeSliceSlice, consts.DataTypeMapAnyAny: - return nil, errors.New(consts.DataTypeSliceSlice.String() + " : data type is not support") + case consts.DataTypeSliceSlice: + return SliceSlice(sourceValue) + case consts.DataTypeMapAnyAny: + return MapAnyAny(sourceValue) case consts.DataTypeSliceMapStringAny: return SliceMapStringAny(sourceValue) case consts.DataTypeMapStrInt: -- 2.36.6 From 7214767a9028e7883e2df462404a47c1b62f6068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Mon, 2 Dec 2024 11:36:03 +0800 Subject: [PATCH 12/14] filter.getValue => gjson_hack.Value --- filter.go | 169 +----------------------------------------------------- 1 file changed, 1 insertion(+), 168 deletions(-) diff --git a/filter.go b/filter.go index b5b1767..07233ec 100644 --- a/filter.go +++ b/filter.go @@ -13,13 +13,8 @@ import ( "reflect" "strings" - "git.zhangdeman.cn/zhangdeman/util" - - "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/tidwall/gjson" "github.com/tidwall/sjson" @@ -133,7 +128,7 @@ func (f *filter) setResult(rule MapRule) error { ) sourceResult := gjson.Get(f.sourceData, rule.SourcePath) - if formatVal, err = f.getValue(rule.DataType, sourceResult, rule.DefaultValue); nil != err { + if formatVal, err = gjson_hack.Value(rule.DataType, sourceResult, rule.DefaultValue); nil != err { return fmt.Errorf("%s = %v can not convert to %s : %s", rule.SourcePath, sourceResult.Value(), rule.DataType, err.Error()) } if reflect.TypeOf(formatVal).Kind() == reflect.Map { @@ -210,165 +205,3 @@ func (f *filter) Parse(receiver interface{}) error { } return json.Unmarshal(f.Byte(), receiver) } - -// getValue 获取值 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 12:25 2022/7/4 -func (f *filter) getValue(dataType consts.DataType, sourceValue gjson.Result, defaultValue string) (any, error) { - sourceValueStr := defaultValue - if sourceValue.Exists() { - str := sourceValue.String() - if len(str) > 0 { - sourceValueStr = str - } - } - - strVal := wrapper.String(sourceValueStr) - - switch dataType { - case consts.DataTypeInt: - intVal := strVal.ToInt() - return intVal.Value, intVal.Err - case consts.DataTypeUint: - uintVal := strVal.ToUint64() - return uintVal.Value, uintVal.Err - case consts.DataTypeBool: - boolVal := strVal.ToBool() - return boolVal.Value, boolVal.Err - case consts.DataTypeFloat: - floatVal := strVal.ToFloat64() - return floatVal.Value, floatVal.Err - case consts.DataTypeString: - return strVal.Value(), nil - case consts.DataTypeAny: - if sourceValue.Exists() { - // 可能存在精度丢失, 原因 : gjson.Value 内置的转换, int64 超过一定大小会存在丢失精度问题 - if sourceValue.Num > 0 { - // 说明是数字 - var res float64 - if err := util.ConvertAssign(&res, sourceValue.String()); nil != err { - return nil, err - } - return res, nil - } - return sourceValue.Value(), nil - } - return defaultValue, nil - case consts.DataTypeSliceAny: - // 任意类型的list - sliceVal := strVal.ToAnySlice() - return sliceVal.Value, sliceVal.Err - case consts.DataTypeSliceInt, consts.DataTypeSliceIntWithChar: - // 任意类型的list - if strings.HasPrefix(strVal.Value(), "[") && strings.HasSuffix(strVal.Value(), "]") { - // 序列化之后的数组 - sliceVal := strVal.ToInt64Slice() - return sliceVal.Value, sliceVal.Err - } - // 分隔的数组 - sliceVal := strVal.ToInt64Slice(",") - return sliceVal.Value, sliceVal.Err - case consts.DataTypeSliceUint, consts.DataTypeSliceUintWithChar: - // 任意类型的list - if strings.HasPrefix(strVal.Value(), "[") && strings.HasPrefix(strVal.Value(), "]") { - // 序列化之后的数组 - sliceVal := strVal.ToUint64Slice() - return sliceVal.Value, sliceVal.Err - } - // 分隔的数组 - sliceVal := strVal.ToUint64Slice(",") - return sliceVal.Value, sliceVal.Err - case consts.DataTypeSliceFloat, consts.DataTypeSliceFloatWithChar: - // 任意类型的list - if strings.HasPrefix(strVal.Value(), "[") && strings.HasPrefix(strVal.Value(), "]") { - // 序列化之后的数组 - sliceVal := strVal.ToFloat64Slice() - return sliceVal.Value, sliceVal.Err - } - // 分隔的数组 - sliceVal := strVal.ToFloat64Slice(",") - return sliceVal.Value, sliceVal.Err - case consts.DataTypeSliceBool, consts.DataTypeSliceBoolWithChar: - // 任意类型的list - if strings.HasPrefix(strVal.Value(), "[") && strings.HasPrefix(strVal.Value(), "]") { - // 序列化之后的数组 - sliceVal := strVal.ToBoolSlice() - return sliceVal.Value, sliceVal.Err - } - // 分隔的数组 - sliceVal := strVal.ToBoolSlice(",") - return sliceVal.Value, sliceVal.Err - case consts.DataTypeSliceString, consts.DataTypeSliceStringWithChar: - // 任意类型的list - if strings.HasPrefix(strVal.Value(), "[") && strings.HasPrefix(strVal.Value(), "]") { - // 序列化之后的数组 - sliceVal := strVal.ToStringSlice() - return sliceVal.Value, sliceVal.Err - } - // 分隔的数组 - sliceVal := strVal.ToStringSlice(",") - return sliceVal.Value, sliceVal.Err - case consts.DataTypeSliceSlice, consts.DataTypeMapAnyAny: - return nil, errors.New(consts.DataTypeSliceSlice.String() + " : data type is not support") - case consts.DataTypeSliceMapStringAny: - if !sourceValue.IsArray() { - return nil, errors.New("data type is not array") - } - var res []map[string]any - err := strVal.ToStruct(&res) - return res, err - case consts.DataTypeMapStrInt: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string]int64 - err := strVal.ToStruct(&res) - return res, err - case consts.DataTypeMapStrUint: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string]uint64 - err := strVal.ToStruct(&res) - return res, err - case consts.DataTypeMapStrFloat: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string]float64 - err := strVal.ToStruct(&res) - return res, err - case consts.DataTypeMapStrBool: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string]bool - err := strVal.ToStruct(&res) - return res, err - case consts.DataTypeMapStrAny: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string]any - err := strVal.ToStruct(&res) - return res, err - case consts.DataTypeMapStrStr: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string]string - err := strVal.ToStruct(&res) - return res, err - case consts.DataTypeMapStrSlice: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string][]any - err := strVal.ToStruct(&res) - return res, err - default: - return nil, errors.New("`" + dataType.String() + "` is not support!") - } -} -- 2.36.6 From 5fc2e0a6138d003a26ee9e2046a017980dee5a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Mon, 2 Dec 2024 14:30:43 +0800 Subject: [PATCH 13/14] =?UTF-8?q?=E4=BC=98=E5=8C=96map=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gjson_hack/precision.go | 67 +++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 43 deletions(-) diff --git a/gjson_hack/precision.go b/gjson_hack/precision.go index 662fc35..2e808e5 100644 --- a/gjson_hack/precision.go +++ b/gjson_hack/precision.go @@ -330,6 +330,22 @@ func SliceSlice(gjsonResult gjson.Result) ([][]any, error) { return res, nil } +// MapStrAny 获取任意map类型的结果 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 14:26 2024/12/2 +func MapStrAny[T string | int64 | uint64 | bool | float64 | []any | map[string]any | any](gjsonResult gjson.Result) (map[string]T, error) { + if !gjsonResult.IsObject() { + return nil, ErrDataIsNotObject + } + var res map[string]T + if err := serialize.JSON.UnmarshalWithNumber([]byte(gjsonResult.String()), &res); nil != err { + return nil, err + } + return res, nil +} + // Value 获取指定的值 // // Author : go_developer@163.com<白茶清欢> @@ -383,55 +399,20 @@ func Value(dataType consts.DataType, sourceValue gjson.Result, defaultValue any) case consts.DataTypeSliceMapStringAny: return SliceMapStringAny(sourceValue) case consts.DataTypeMapStrInt: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string]int64 - err := strVal.ToStruct(&res) - return res, err + return MapStrAny[int64](sourceValue) case consts.DataTypeMapStrUint: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string]uint64 - err := strVal.ToStruct(&res) - return res, err + return MapStrAny[uint64](sourceValue) case consts.DataTypeMapStrFloat: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string]float64 - err := strVal.ToStruct(&res) - return res, err + return MapStrAny[float64](sourceValue) case consts.DataTypeMapStrBool: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string]bool - err := strVal.ToStruct(&res) - return res, err + return MapStrAny[bool](sourceValue) case consts.DataTypeMapStrAny: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string]any - err := strVal.ToStruct(&res) - return res, err + return MapStrAny[any](sourceValue) case consts.DataTypeMapStrStr: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string]string - err := strVal.ToStruct(&res) - return res, err + return MapStrAny[string](sourceValue) case consts.DataTypeMapStrSlice: - if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject - } - var res map[string][]any - err := strVal.ToStruct(&res) - return res, err + return MapStrAny[[]any](sourceValue) default: - return nil, errors.New("`" + dataType.String() + "` is not support!") + return nil, errors.New("data_type = `" + dataType.String() + "` is not support!") } } -- 2.36.6 From 5b509aaee7e50bd4728e622c09b18b8d9374082a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Mon, 2 Dec 2024 14:34:03 +0800 Subject: [PATCH 14/14] =?UTF-8?q?=E6=95=B0=E6=8D=AE=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=A4=84=E7=90=86=E6=94=AF=E6=8C=81=E5=AF=B9=E6=8C=87=E9=92=88?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gjson_hack/precision.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gjson_hack/precision.go b/gjson_hack/precision.go index 2e808e5..328c07b 100644 --- a/gjson_hack/precision.go +++ b/gjson_hack/precision.go @@ -141,6 +141,8 @@ func Any(sourceValue gjson.Result) (any, error) { // // Date : 14:28 2024/12/1 func getRealDataType(dataType consts.DataType, sourceValue gjson.Result) consts.DataType { + // 指针数据类型, 转换为普通数据类型处理 + dataType = consts.DataType(strings.TrimLeft(dataType.String(), "*")) if dataType == consts.DataTypeAny { if sourceValue.IsObject() { dataType = consts.DataTypeMapAnyAny -- 2.36.6