增加json数据过滤能力
This commit is contained in:
158
filter/filter.go
Normal file
158
filter/filter.go
Normal file
@ -0,0 +1,158 @@
|
||||
// Package filter ...
|
||||
//
|
||||
// Description : filter ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2024-04-07 21:59
|
||||
package filter
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.zhangdeman.cn/zhangdeman/data_mask/define"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/tidwall/sjson"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Execute 数据转换
|
||||
//
|
||||
// Author : go_developer@163.com<张德满>
|
||||
//
|
||||
// Date : 12:39 2024/3/26
|
||||
func Execute(sourceData string, convertRule []*define.FilterRule) *Transform {
|
||||
sourceData = strings.TrimSpace(sourceData)
|
||||
t := &Transform{
|
||||
sourceData: sourceData,
|
||||
ruleList: convertRule,
|
||||
result: "{}",
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// Transform 转换
|
||||
//
|
||||
// Author : go_developer@163.com<张德满>
|
||||
//
|
||||
// Date : 10:56 2024/3/27
|
||||
type Transform struct {
|
||||
sourceData string
|
||||
ruleList []*define.FilterRule
|
||||
result string
|
||||
}
|
||||
|
||||
// Execute 执行
|
||||
//
|
||||
// Author : go_developer@163.com<张德满>
|
||||
//
|
||||
// Date : 10:57 2024/3/27
|
||||
func (t *Transform) Execute() error {
|
||||
sourceResult := gjson.Parse(t.sourceData)
|
||||
if !sourceResult.IsObject() {
|
||||
return errors.New("source data is not object")
|
||||
}
|
||||
if err := t.checkRule(); nil != err {
|
||||
return err
|
||||
}
|
||||
for _, itemRule := range t.ruleList {
|
||||
if err := t.rewrite(itemRule); nil != err {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetResult 获取处理结果
|
||||
//
|
||||
// Author : go_developer@163.com<张德满>
|
||||
//
|
||||
// Date : 11:32 2024/3/27
|
||||
func (t *Transform) GetResult() string {
|
||||
return t.result
|
||||
}
|
||||
|
||||
// checkRule 校验规则
|
||||
//
|
||||
// Author : go_developer@163.com<张德满>
|
||||
//
|
||||
// Date : 11:18 2024/3/27
|
||||
func (t *Transform) checkRule() error {
|
||||
for _, itemRule := range t.ruleList {
|
||||
itemRule.SourceDataPath = strings.TrimRight(itemRule.SourceDataPath, ".[]")
|
||||
itemRule.TargetDataPath = strings.TrimRight(itemRule.TargetDataPath, ".[]")
|
||||
fromPathArr := strings.Split(itemRule.SourceDataPath, "[]")
|
||||
targetPathArr := strings.Split(itemRule.TargetDataPath, "[]")
|
||||
if len(targetPathArr) > len(fromPathArr) {
|
||||
return errors.New("slice path config invalid : " + itemRule.SourceDataPath + " -> " + itemRule.TargetDataPath)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// rewrite 数据重写
|
||||
//
|
||||
// Author : go_developer@163.com<张德满>
|
||||
//
|
||||
// Date : 11:25 2024/3/27
|
||||
func (t *Transform) rewrite(rule *define.FilterRule) error {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
|
||||
sourceResult := gjson.Get(t.sourceData, rule.SourceDataPath)
|
||||
if !sourceResult.Exists() {
|
||||
if rule.IsRequired {
|
||||
return errors.New(rule.SourceDataPath + " is not exist, but required")
|
||||
}
|
||||
if strings.Contains(rule.SourceDataPath, "[]") {
|
||||
return t.rewriteForSlice(rule)
|
||||
}
|
||||
if t.result, err = sjson.Set(t.result, rule.TargetDataPath, rule.DefaultValue); nil != err {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
t.result, err = sjson.Set(t.result, rule.TargetDataPath, sourceResult.Value())
|
||||
return nil
|
||||
}
|
||||
|
||||
// rewriteForSlice 数组重写
|
||||
//
|
||||
// Author : go_developer@163.com<张德满>
|
||||
//
|
||||
// Date : 15:22 2024/3/27
|
||||
func (t *Transform) rewriteForSlice(rule *define.FilterRule) error {
|
||||
pathArr := strings.Split(rule.SourceDataPath, ".[].")
|
||||
sliceUnfoldResult := t.unfoldSourceSliceData(t.sourceData, pathArr[0:len(pathArr)-1], nil)
|
||||
targetArr := strings.Split(rule.TargetDataPath, ".[].")
|
||||
for idx, itemRes := range sliceUnfoldResult {
|
||||
t.result, _ = sjson.Set(t.result, fmt.Sprintf("%v.%v.%v", targetArr[0], idx, targetArr[1]), itemRes.Get(pathArr[len(pathArr)-1]).Value())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// unfoldSourceSliceData 展开元数据的数组, 平铺
|
||||
//
|
||||
// Author : go_developer@163.com<张德满>
|
||||
//
|
||||
// Date : 17:39 2024/3/27
|
||||
func (t *Transform) unfoldSourceSliceData(sourceData string, pathList []string, res []gjson.Result) []gjson.Result {
|
||||
if nil == res {
|
||||
res = make([]gjson.Result, 0)
|
||||
}
|
||||
|
||||
arrRes := gjson.Get(sourceData, pathList[0]).Array()
|
||||
if len(pathList) == 1 {
|
||||
for _, itemRes := range arrRes {
|
||||
res = append(res, itemRes)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
for i := 0; i < len(arrRes)-1; i++ {
|
||||
res = t.unfoldSourceSliceData(arrRes[i].String(), pathList[1:], res)
|
||||
}
|
||||
|
||||
return t.unfoldSourceSliceData(arrRes[len(arrRes)-1].String(), pathList[1:], res)
|
||||
}
|
Reference in New Issue
Block a user