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!") + } +}