package exprhelpers import ( "encoding/json" "errors" "fmt" "strings" "github.com/buger/jsonparser" log "github.com/sirupsen/logrus" ) // func JsonExtractLib(jsblob string, target ...string) string { func JsonExtractLib(params ...any) (any, error) { jsblob := params[0].(string) target := params[1].([]string) value, dataType, _, err := jsonparser.Get( jsonparser.StringToBytes(jsblob), target..., ) if err != nil { if errors.Is(err, jsonparser.KeyPathNotFoundError) { log.Debugf("%+v doesn't exist", target) return "", nil } log.Errorf("jsonExtractLib : %+v : %s", target, err) return "", nil } if dataType == jsonparser.NotExist { log.Debugf("%+v doesn't exist", target) return "", nil } strvalue := string(value) return strvalue, nil } // func JsonExtractUnescape(jsblob string, target ...string) string { func JsonExtractUnescape(params ...any) (any, error) { var value string var err error jsblob := params[0].(string) switch v := params[1].(type) { case string: target := v value, err = jsonparser.GetString( jsonparser.StringToBytes(jsblob), target, ) case []string: target := v value, err = jsonparser.GetString( jsonparser.StringToBytes(jsblob), target..., ) } if err != nil { if errors.Is(err, jsonparser.KeyPathNotFoundError) { log.Debugf("%+v doesn't exist", params[1]) return "", nil } log.Errorf("JsonExtractUnescape : %+v : %s", params[1], err) return "", nil } log.Tracef("extract path %+v", params[1]) return value, nil } // func JsonExtract(jsblob string, target string) string { func JsonExtract(params ...any) (any, error) { jsblob := params[0].(string) target := params[1].(string) if !strings.HasPrefix(target, "[") { target = strings.ReplaceAll(target, "[", ".[") } fullpath := strings.Split(target, ".") log.Tracef("extract path %+v", fullpath) return JsonExtractLib(jsblob, fullpath) } func jsonExtractType(jsblob string, target string, t jsonparser.ValueType) ([]byte, error) { if !strings.HasPrefix(target, "[") { target = strings.ReplaceAll(target, "[", ".[") } fullpath := strings.Split(target, ".") log.Tracef("extract path %+v", fullpath) value, dataType, _, err := jsonparser.Get( jsonparser.StringToBytes(jsblob), fullpath..., ) if err != nil { if errors.Is(err, jsonparser.KeyPathNotFoundError) { log.Debugf("Key %+v doesn't exist", target) return nil, fmt.Errorf("key %s does not exist", target) } log.Errorf("jsonExtractType : %s : %s", target, err) return nil, fmt.Errorf("jsonExtractType: %s : %w", target, err) } if dataType != t { log.Errorf("jsonExtractType : expected type %s for target %s but found %s", t, target, dataType.String()) return nil, fmt.Errorf("jsonExtractType: expected type %s for target %s but found %s", t, target, dataType.String()) } return value, nil } // func JsonExtractSlice(jsblob string, target string) []interface{} { func JsonExtractSlice(params ...any) (any, error) { jsblob := params[0].(string) target := params[1].(string) value, err := jsonExtractType(jsblob, target, jsonparser.Array) if err != nil { log.Errorf("JsonExtractSlice : %s", err) return []interface{}(nil), nil } s := make([]interface{}, 0) err = json.Unmarshal(value, &s) if err != nil { log.Errorf("JsonExtractSlice: could not convert '%s' to slice: %s", value, err) return []interface{}(nil), nil } return s, nil } // func JsonExtractObject(jsblob string, target string) map[string]interface{} { func JsonExtractObject(params ...any) (any, error) { jsblob := params[0].(string) target := params[1].(string) value, err := jsonExtractType(jsblob, target, jsonparser.Object) if err != nil { log.Errorf("JsonExtractObject: %s", err) return map[string]interface{}(nil), nil } s := make(map[string]interface{}) err = json.Unmarshal(value, &s) if err != nil { log.Errorf("JsonExtractObject: could not convert '%s' to map[string]interface{}: %s", value, err) return map[string]interface{}(nil), nil } return s, nil } // func ToJson(obj interface{}) string { func ToJson(params ...any) (any, error) { obj := params[0] b, err := json.Marshal(obj) if err != nil { log.Errorf("ToJson : %s", err) return "", nil } return string(b), nil } // Func UnmarshalJSON(jsonBlob []byte, target interface{}) error { func UnmarshalJSON(params ...any) (any, error) { jsonBlob := params[0].(string) target := params[1].(map[string]interface{}) key := params[2].(string) var out interface{} err := json.Unmarshal([]byte(jsonBlob), &out) if err != nil { log.WithField("line", jsonBlob).Errorf("UnmarshalJSON : %s", err) return nil, err } target[key] = out return nil, nil }