diff --git a/gjson_hack/error.go b/gjson_hack/error.go index 5e65ef8..c42c5e8 100644 --- a/gjson_hack/error.go +++ b/gjson_hack/error.go @@ -7,9 +7,9 @@ // Date : 2024-11-30 19:14 package gjson_hack -import "errors" - var ( - ErrDataIsNotObject = errors.New("data is not an object") - ErrDataIsNotArray = errors.New("data is not an array") + ErrDataPathNotFound = "data_path_not_found" + ErrDataIsNotObject = "data_is_not_object" + ErrDataIsNotArray = "data_is_not_an_array" + ErrDataTypeIsNotSupport = "data_type_is_not_support" ) diff --git a/gjson_hack/precision.go b/gjson_hack/precision.go index d2c3461..3677da7 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/exception" "git.zhangdeman.cn/zhangdeman/serialize" "git.zhangdeman.cn/zhangdeman/util" "git.zhangdeman.cn/zhangdeman/wrapper" @@ -22,7 +23,7 @@ import ( // Author : go_developer@163.com<白茶清欢> // // Date : 10:57 2024/11/27 -func Number[T int64 | uint64 | float64](gjsonResult gjson.Result, numberReceiver *T) error { +func Number(gjsonResult gjson.Result, numberReceiver any) error { if !gjsonResult.Exists() { return errors.New("gjson result not found") } @@ -40,9 +41,9 @@ func Number[T int64 | uint64 | float64](gjsonResult gjson.Result, numberReceiver // Author : go_developer@163.com<白茶清欢> // // Date : 11:19 2024/11/27 -func Int(gjsonResult gjson.Result) (int64, error) { - var intResult int64 - if err := Number(gjsonResult, &intResult); nil != err { +func Int[T int8 | int16 | int32 | int64 | int](gjsonResult gjson.Result) (T, error) { + var intResult T + if err := Number[T](gjsonResult, &intResult); nil != err { return 0, err } return intResult, nil @@ -53,25 +54,25 @@ func Int(gjsonResult gjson.Result) (int64, error) { // Author : go_developer@163.com<白茶清欢> // // Date : 11:21 2024/11/27 -func Uint(gjsonResult gjson.Result) (uint64, error) { - var uintResult uint64 - if err := Number(gjsonResult, &uintResult); nil != err { +func Uint[T uint8 | uint16 | uint32 | uint64 | uint](gjsonResult gjson.Result) (T, error) { + var uintResult T + if err := Number[T](gjsonResult, &uintResult); nil != err { return 0, err } return uintResult, nil } -// Float64 转为float64 +// Float 转为float64 // // Author : go_developer@163.com<白茶清欢> // // Date : 11:24 2024/11/27 -func Float64(gjsonResult gjson.Result) (float64, error) { - var float64Result float64 - if err := Number(gjsonResult, &float64Result); nil != err { +func Float[T float32 | float64](gjsonResult gjson.Result) (T, error) { + var floatResult T + if err := Number[T](gjsonResult, &floatResult); nil != err { return 0, err } - return float64Result, nil + return floatResult, nil } // String 获取字符串值 @@ -96,8 +97,11 @@ func String(sourceValue gjson.Result, defaultValue string) string { // // Date : 17:48 2024/12/1 func MapAnyAny(sourceValue gjson.Result) (map[string]any, error) { + if !sourceValue.Exists() { + return nil, exception.New(ErrDataPathNotFound, nil, "data path not found") + } if !sourceValue.IsObject() { - return nil, ErrDataIsNotObject + return nil, exception.New(ErrDataIsNotObject, nil) } res := make(map[string]any) sourceValue.ForEach(func(key, value gjson.Result) bool { @@ -117,13 +121,33 @@ func Any(sourceValue gjson.Result) (any, error) { return nil, nil } // 可能存在精度丢失, 原因 : gjson.Value 内置的转换, int64 超过一定大小会存在丢失精度问题 - if sourceValue.Num > 0 || sourceValue.Num < 0 { + if sourceValue.Type == gjson.Number { // 说明是数字 - var res float64 - if err := util.ConvertAssign(&res, sourceValue.String()); nil != err { - return nil, err + if strings.Contains(sourceValue.String(), ".") { + // 小数 + var res float64 + if err := Number[float64](sourceValue, &res); nil != err { + return nil, err + } + return res, nil + } else { + // 整数 + if strings.HasPrefix(sourceValue.String(), "-") { + // 负数 + var res int64 + if err := Number[int64](sourceValue, &res); nil != err { + return nil, err + } + return res, nil + } else { + // 正数 + var res uint64 + if err := Number[uint64](sourceValue, &res); nil != err { + return nil, err + } + return res, nil + } } - return res, nil } if sourceValue.IsObject() { return MapAnyAny(sourceValue) @@ -260,7 +284,6 @@ 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, "]") { @@ -307,8 +330,8 @@ func SliceMapStringAny(gjsonResult gjson.Result) ([]map[string]any, error) { strVal := strings.TrimSpace(gjsonResult.String()) // 任意类型的list - if !strings.HasPrefix(strVal, "[") || !strings.HasSuffix(strVal, "]") { - return nil, ErrDataIsNotArray + if !gjsonResult.IsArray() { + return nil, exception.New(ErrDataIsNotArray, nil) } var res []map[string]any if err := serialize.JSON.UnmarshalWithNumber([]byte(strVal), &res); nil != err { @@ -329,8 +352,8 @@ func SliceSlice(gjsonResult gjson.Result) ([][]any, error) { strVal := strings.TrimSpace(gjsonResult.String()) // 任意类型的list - if !strings.HasPrefix(strVal, "[") || !strings.HasSuffix(strVal, "]") { - return nil, ErrDataIsNotArray + if !gjsonResult.IsArray() { + return nil, exception.New(ErrDataIsNotArray, nil) } var res [][]any if err := serialize.JSON.UnmarshalWithNumber([]byte(strVal), &res); nil != err { @@ -346,7 +369,7 @@ func SliceSlice(gjsonResult gjson.Result) ([][]any, error) { // 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 + return nil, exception.New(ErrDataIsNotArray, nil) } var res map[string]T if err := serialize.JSON.UnmarshalWithNumber([]byte(gjsonResult.String()), &res); nil != err { @@ -369,12 +392,30 @@ func Value(dataType consts.DataType, sourceValue gjson.Result, defaultValue any) dataType = getRealDataType(dataType, sourceValue) strVal := wrapper.String(sourceValue.String()) switch dataType { - case consts.DataTypeInt, consts.DataTypeInt8, consts.DataTypeInt16, consts.DataTypeInt32, consts.DataTypeInt64: - return Int(sourceValue) - case consts.DataTypeUint, consts.DataTypeUint8, consts.DataTypeUint16, consts.DataTypeUint32, consts.DataTypeUint64: - return Uint(sourceValue) - case consts.DataTypeFloat64, consts.DataTypeFloat32: - return Float64(sourceValue) + case consts.DataTypeInt: + return Int[int](sourceValue) + case consts.DataTypeInt8: + return Int[int8](sourceValue) + case consts.DataTypeInt16: + return Int[int16](sourceValue) + case consts.DataTypeInt32: + return Int[int32](sourceValue) + case consts.DataTypeInt64: + return Int[int64](sourceValue) + case consts.DataTypeUint: + return Uint[uint](sourceValue) + case consts.DataTypeUint8: + return Uint[uint8](sourceValue) + case consts.DataTypeUint16: + return Uint[uint16](sourceValue) + case consts.DataTypeUint32: + return Uint[uint32](sourceValue) + case consts.DataTypeUint64: + return Uint[uint64](sourceValue) + case consts.DataTypeFloat64: + return Float[float64](sourceValue) + case consts.DataTypeFloat32: + return Float[float32](sourceValue) case consts.DataTypeBool: boolVal := strVal.ToBool() return boolVal.Value, boolVal.Err @@ -423,6 +464,6 @@ func Value(dataType consts.DataType, sourceValue gjson.Result, defaultValue any) case consts.DataTypeMapStrSlice: return MapStrAny[[]any](sourceValue) default: - return nil, errors.New("data_type = `" + dataType.String() + "` is not support!") + return nil, exception.New(ErrDataTypeIsNotSupport, map[string]any{"data_type": dataType.String()}) } } diff --git a/go.mod b/go.mod index 2db8213..b615eb2 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module git.zhangdeman.cn/zhangdeman/json_filter -go 1.21 +go 1.23.0 -toolchain go1.21.5 +toolchain go1.24.3 require ( - git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250328040304-7e4a6f9f148c + git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250425024726-cc17224cb995 git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda - git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd + git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250504055908-8d68e6106ea9 git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740 github.com/pkg/errors v0.9.1 @@ -18,6 +18,7 @@ require ( ) require ( + git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250510123912-a0d52fc093ab // indirect git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect github.com/BurntSushi/toml v1.5.0 // indirect github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect @@ -26,6 +27,7 @@ require ( github.com/jtolds/gls v4.20.0+incompatible // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mozillazg/go-pinyin v0.20.0 // indirect + github.com/sbabiv/xml2map v1.2.1 // indirect github.com/smarty/assertions v1.15.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/tidwall/match v1.1.1 // indirect diff --git a/go.sum b/go.sum index 7c6d66a..c55f990 100644 --- a/go.sum +++ b/go.sum @@ -2,12 +2,18 @@ git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321102241-d6e86b64f7ca h1:uxjzbY git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250321102241-d6e86b64f7ca/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250328040304-7e4a6f9f148c h1:cl3gQGXQpJ8ugDs0C/hQLfcvF4lGBm5BeABLvROFDoM= git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250328040304-7e4a6f9f148c/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= +git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250425024726-cc17224cb995 h1:LmPRAf0AsxRVFPibdpZR89ajlsz8hof2IvMMyTqiEq4= +git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250425024726-cc17224cb995/go.mod h1:5p8CEKGBxi7qPtTXDI3HDmqKAfIm5i/aBWdrbkbdNjc= git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda h1:bMD6r9gjRy7cO+T4zRQVYAesgIblBdTnhzT1vN5wjvI= git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda/go.mod h1:dT0rmHcJ9Z9IqWeMIt7YzR88nKkNV2V3dfG0j9Q6lK0= +git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250510123912-a0d52fc093ab h1:O0XaAKKb8qrjcjewonmKfnRsMFoCfJF+tUv6RfhRe94= +git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250510123912-a0d52fc093ab/go.mod h1:Voc8J4ordx7nuMWpgACXXZULQy7ZIuBzcEIoS8VnDIw= git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQMuJ4xNfP2Abl1Msmpa3fASLWYkNlqDFF/6GN0Y= git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI= git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd h1:q7GG14qgXKB4MEXQFOe7/UYebsqMfPaSX80TcPdOosI= git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs= +git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250504055908-8d68e6106ea9 h1:/GLQaFoLb+ciHOtAS2BIyPNnf4O5ME3AC5PUaJY9kfs= +git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250504055908-8d68e6106ea9/go.mod h1:ABJ655C5QenQNOzf7LjCe4sSB52CXvaWLX2Zg4uwDJY= git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI= git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI= git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740 h1:zPUoylfJTbc0EcxW+NEzOTBmoeFZ2I/rLFBnEzxb4Wk= @@ -32,6 +38,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sbabiv/xml2map v1.2.1 h1:1lT7t0hhUvXZCkdxqtq4n8/ZCnwLWGq4rDuDv5XOoFE= +github.com/sbabiv/xml2map v1.2.1/go.mod h1:2TPoAfcaM7+Sd4iriPvzyntb2mx7GY+kkQpB/GQa/eo= github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=