159 lines
3.9 KiB
Go
159 lines
3.9 KiB
Go
// 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)
|
|
}
|