// Package filter ... // // Description : filter ... // // Author : go_developer@163.com<白茶清欢> // // Date : 2022-07-04 17:47 package filter import ( "encoding/json" "fmt" "strings" "github.com/tidwall/gjson" "github.com/tidwall/sjson" "errors" "git.zhangdeman.cn/zhangdeman/util" ) // NewFilter 过滤器实例 // // Author : go_developer@163.com<白茶清欢> // // Date : 11:54 2022/7/4 func NewFilter(sourceData string, filterRuleList []MapRule) *filter { return &filter{ sourceData: sourceData, formatResult: "{}", filterRuleList: filterRuleList, } } // filter 数据过滤 // // Author : go_developer@163.com<白茶清欢> // // Date : 11:58 2022/7/4 type filter struct { sourceData string formatResult string filterRuleList []MapRule } // Deal ... // // Author : go_developer@163.com<白茶清欢> // // Date : 11:59 2022/7/4 func (f *filter) Deal() error { var ( err error formatVal interface{} ) for _, rule := range f.filterRuleList { if f.IsArray(rule) { // 对于list的处理 if err = f.handleArray(rule); nil != err { return err } continue } sourceResult := gjson.Get(f.sourceData, rule.SourcePath) var ( sourceVal string ) if !sourceResult.Exists() { // 不存在, 使用默认值 sourceVal = rule.DefaultValue } else { sourceVal = sourceResult.String() } if formatVal, err = f.getValue(rule.DataType, sourceVal); nil != err { return fmt.Errorf("%s = %v can not convert to %s : %s", rule.SourcePath, sourceResult.Value(), rule.DataType, err.Error()) } if f.formatResult, err = sjson.Set(f.formatResult, rule.MapPath, formatVal); nil != err { return err } } return nil } // IsArray 判断是否为数组 // // Author : zhangdeman001@ke.com<张德满> // // Date : 17:48 2023/1/1 func (f *filter) IsArray(rule MapRule) bool { return strings.Contains(rule.SourcePath, "[]") } // handleArray 处理数组(最复杂的场景) // // Author : go_developer@163.com<白茶清欢> // // Date : 17:41 2023/1/1 func (f *filter) handleArray(rule MapRule) error { var ( err error ) sourcePathArray := strings.Split(rule.SourcePath, "[]") for idx, item := range sourcePathArray { sourcePathArray[idx] = strings.Trim(item, ".") } mapPathArray := strings.Split(strings.TrimRight(rule.MapPath, ".[]"), "[]") for idx, item := range mapPathArray { mapPathArray[idx] = strings.Trim(item, ".") } 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 { return err } return nil } return nil } // extraFinalResult 提取全部最底层结果 // // Author : zhangdeman001@ke.com<张德满> // // Date : 14:00 2023/1/2 func (f *filter) getAllFinalData(res *[]string, resultList []gjson.Result, pathArr []string) { if len(pathArr) == 1 { for _, item := range resultList { *res = append(*res, item.Get(pathArr[0]).String()) } return } for _, item := range resultList { f.getAllFinalData(res, item.Array(), pathArr[1:]) } return } // String 获取格式化之后的字符串 // // Author : go_developer@163.com<白茶清欢> // // Date : 21:18 2022/12/31 func (f *filter) String() string { return f.formatResult } // Byte 获取格式化之后的字节数组 // // Author : zhangdeman001@ke.com<张德满> // // Date : 21:18 2022/12/31 func (f *filter) Byte() []byte { return []byte(f.String()) } // Parse 解析返回结果 // // Author : go_developer@163.com<白茶清欢> // // Date : 21:20 2022/12/31 func (f *filter) Parse(receiver interface{}) error { if nil == receiver { return errors.New("receiver is nil") } return json.Unmarshal(f.Byte(), receiver) } // getValue 获取值 // // Author : go_developer@163.com<白茶清欢> // // Date : 12:25 2022/7/4 func (f *filter) getValue(dataType string, defaultValue string) (interface{}, error) { switch dataType { case "int8": fallthrough case "int16": fallthrough case "int32": fallthrough case "int64": fallthrough case "int": var ( err error val int64 ) err = util.ConvertAssign(&val, defaultValue) return val, err case "uint8": fallthrough case "uint16": fallthrough case "uint32": fallthrough case "uint64": fallthrough case "uint": var ( err error val uint64 ) err = util.ConvertAssign(&val, defaultValue) return val, err case "bool": var ( err error val bool ) err = util.ConvertAssign(&val, defaultValue) return val, err case "float32": fallthrough case "float64": var ( err error val float64 ) err = util.ConvertAssign(&val, defaultValue) return val, err case "string": return defaultValue, nil default: return nil, errors.New(dataType + " is not support!") } }