// Package filter ... // // Description : filter ... // // Author : go_developer@163.com<白茶清欢> // // Date : 2022-07-04 17:47 package filter import ( "fmt" "git.zhangdeman.cn/zhangdeman/json_filter/abstract" "git.zhangdeman.cn/zhangdeman/json_filter/implement" "strings" "errors" "git.zhangdeman.cn/zhangdeman/json_filter/gjson_hack" "github.com/tidwall/gjson" ) func NewFilterWithJson(sourceData string, filterRuleList []MapRule, jsonRead abstract.IJsonRead, jsonWrite abstract.IJsonWrite) *filter { if nil == jsonRead { jsonRead = implement.NewGjsonRead(sourceData) } if nil == jsonWrite { jsonWrite = implement.NewSjsonWrite() } return &filter{ jsonRaad: jsonRead, jsonWrite: jsonWrite, sourceData: sourceData, filterRuleList: filterRuleList, } } // NewFilter 过滤器实例 // // Author : go_developer@163.com<白茶清欢> // // Date : 11:54 2022/7/4 func NewFilter(sourceData string, filterRuleList []MapRule) *filter { return &filter{ sourceData: sourceData, jsonRaad: implement.NewGjsonRead(sourceData), jsonWrite: implement.NewSjsonWrite(), filterRuleList: filterRuleList, } } // filter 数据过滤 // // Author : go_developer@163.com<白茶清欢> // // Date : 11:58 2022/7/4 type filter struct { jsonRaad abstract.IJsonRead jsonWrite abstract.IJsonWrite sourceData string filterRuleList []MapRule } // Deal ... // // Author : go_developer@163.com<白茶清欢> // // Date : 11:59 2022/7/4 func (f *filter) Deal() error { var ( err error ) for _, rule := range f.filterRuleList { if len(rule.TargetPath) == 0 { // 未配置目标路径则, 目标路径和源路径保持一致 rule.TargetPath = rule.SourcePath } if f.IsArray(rule) { // 对于list的处理, 展开层级, 并自动追加到f.filterRuleList 后面 if err = f.handleArray(rule); nil != err { return err } continue } if err = f.setResult(rule); 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, gjson_hack.ArrayIdxTpl) } // handleArray 处理数组(最复杂的场景) // // Author : go_developer@163.com<白茶清欢> // // Date : 17:41 2023/1/1 func (f *filter) handleArray(rule MapRule) error { // 对于list的处理, 展开层级, 并自动追加到f.filterRuleList 后面 var ( err error ) expendRes := &gjson_hack.ExpendArrayResult{ PathList: make([]string, 0), PathMap: map[string]string{}, } if err = gjson_hack.ExpandArrayPath(f.sourceData, rule.SourcePath, rule.TargetPath, expendRes); nil != err { return 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 } // setResult 设置结果 // // Author : go_developer@163.com<白茶清欢> // // Date : 19:03 2024/11/30 func (f *filter) setResult(rule MapRule) error { var ( err error formatVal any ) if formatVal, err = f.jsonRaad.Value(rule.SourcePath, rule.DataType.String(), rule.DefaultValue); nil != err { return fmt.Errorf("%s = %v can not convert to %s : %s", rule.SourcePath, gjson.Get(f.sourceData, rule.SourcePath).String(), rule.DataType, err.Error()) } if err = f.jsonWrite.Set(rule.TargetPath, formatVal); nil != err { return err } 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.jsonWrite.Result() } // 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 any) error { if nil == receiver { return errors.New("receiver is nil") } return f.jsonWrite.MapWithReceiver(receiver) // return json.Unmarshal(f.Byte(), receiver) }