// Package filter ... // // Description : filter ... // // Author : go_developer@163.com<白茶清欢> // // Date : 2022-07-04 17:47 package filter import ( "encoding/json" "fmt" "github.com/tidwall/sjson" "strings" "git.zhangdeman.cn/zhangdeman/util" "github.com/pkg/errors" "github.com/tidwall/gjson" ) // 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, "[]") mapPathArray := strings.Split(rule.MapPath, "[]") if len(sourcePathArray) != len(mapPathArray) { if len(mapPathArray) != 1 { return errors.New("map rule is invalid") } // 提取某一个list下的字段, 组成一个list res := make([]string, 0) 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) == 0 { for _, item := range resultList { res = append(res, item.String()) } return } for _, item := range resultList { f.extraFinalResult(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!") } }