// Package json_tool ... // // Description : json_tool ... // // Author : go_developer@163.com<张德满> // // Date : 2022/01/22 9:19 PM package json_tool import ( "github.com/pkg/errors" "github.com/tidwall/gjson" "github.com/tidwall/sjson" "log/slog" "os" "strings" ) const ( virtualRoot = "__virtual__root" ) // FilterOption 过滤选项 // // Author : go_developer@163.com<白茶清欢> // // Date : 17:59 2023/9/1 type FilterOption struct { DebugModel bool // 调试模式 LogInstance *slog.Logger // 日志实例 } // FilterDataRule 参数过滤规则 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/22 9:44 PM type FilterDataRule struct { SourceKey string // 原始数据路径 MapKey string // 提取后映射到的数据路径 DefaultValue interface{} // 原始数据路径不存在时的默认值 WithDefault bool // 是否使用默认值 } // NewDataFilter 获取数据过滤方法实例 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/22 9:50 PM func NewDataFilter(source string, filterRule []*FilterDataRule, filterOption *FilterOption) *DataFilter { if nil == filterOption { filterOption = &FilterOption{} } if filterOption.DebugModel && nil == filterOption.LogInstance { filterOption.LogInstance = slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ Level: slog.LevelDebug, })) slog.SetDefault(filterOption.LogInstance) } return &DataFilter{ source: source, filterRule: filterRule, rewriteResult: "{}", filterOption: filterOption, } } // DataFilter 数据过滤 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/22 9:20 PM type DataFilter struct { source string filterRule []*FilterDataRule rewriteResult string // json数据重写结果 filterOption *FilterOption // 过滤选项 } // Filter 数据过滤 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022/1/22 9:36 PM func (df *DataFilter) Filter() (string, error) { df.logPrint(logLevelInfo, "输入的原始数据", slog.String("source_data", df.source)) var ( err error ) for _, itemRule := range df.filterRule { if !df.isArrPath(itemRule.SourceKey) && !df.isArrPath(itemRule.MapKey) { // 输入输出均不是数组, 最简单的场景 if err = df.setKV(itemRule); nil != err { return "", err } } } return df.rewriteResult, nil } // isArrPath 是否为数组路径 // // Author : go_developer@163.com<白茶清欢> // // Date : 16:00 2023/9/1 func (df *DataFilter) isArrPath(path string) bool { return strings.Contains(path, "[]") } // setKV 设置相关值 // // Author : go_developer@163.com<白茶清欢> // // Date : 16:03 2023/9/1 func (df *DataFilter) setKV(rule *FilterDataRule) error { var ( err error ) sourceValue := gjson.Get(df.source, rule.SourceKey) if sourceValue.Exists() { // 原始数据存在对应路径 df.rewriteResult, err = sjson.Set(df.rewriteResult, rule.MapKey, sourceValue.Value()) return err } if !rule.WithDefault { // 路径不存在, 且禁用默认值 return errors.New(rule.SourceKey + " : source path not found, and default value is forbidden") } // 使用默认值填充 df.rewriteResult, err = sjson.Set(df.rewriteResult, rule.MapKey, rule.DefaultValue) return err } // logPrint 打印日志 // // Author : go_developer@163.com<白茶清欢> // // Date : 18:00 2023/9/1 func (df *DataFilter) logPrint(level string, msg string, logAttr ...interface{}) { if !df.filterOption.DebugModel { // 未开启调试模式 return } switch level { case logLevelFatal: slog.Error(msg, logAttr...) case logLevelWarn: slog.Warn(msg, logAttr...) case logLevelInfo: slog.Info(msg, logAttr...) case logLevelDebug: slog.Debug(msg, logAttr...) } } // 日志等级定义 const ( logLevelFatal = "FATAL" logLevelWarn = "WARN" logLevelInfo = "INFO" logLevelDebug = "DEBUG" )