jsonextract.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package exprhelpers
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "strings"
  7. "github.com/buger/jsonparser"
  8. log "github.com/sirupsen/logrus"
  9. )
  10. // func JsonExtractLib(jsblob string, target ...string) string {
  11. func JsonExtractLib(params ...any) (any, error) {
  12. jsblob := params[0].(string)
  13. target := params[1].([]string)
  14. value, dataType, _, err := jsonparser.Get(
  15. jsonparser.StringToBytes(jsblob),
  16. target...,
  17. )
  18. if err != nil {
  19. if errors.Is(err, jsonparser.KeyPathNotFoundError) {
  20. log.Debugf("%+v doesn't exist", target)
  21. return "", nil
  22. }
  23. log.Errorf("jsonExtractLib : %+v : %s", target, err)
  24. return "", nil
  25. }
  26. if dataType == jsonparser.NotExist {
  27. log.Debugf("%+v doesn't exist", target)
  28. return "", nil
  29. }
  30. strvalue := string(value)
  31. return strvalue, nil
  32. }
  33. // func JsonExtractUnescape(jsblob string, target ...string) string {
  34. func JsonExtractUnescape(params ...any) (any, error) {
  35. var value string
  36. var err error
  37. jsblob := params[0].(string)
  38. switch v := params[1].(type) {
  39. case string:
  40. target := v
  41. value, err = jsonparser.GetString(
  42. jsonparser.StringToBytes(jsblob),
  43. target,
  44. )
  45. case []string:
  46. target := v
  47. value, err = jsonparser.GetString(
  48. jsonparser.StringToBytes(jsblob),
  49. target...,
  50. )
  51. }
  52. if err != nil {
  53. if errors.Is(err, jsonparser.KeyPathNotFoundError) {
  54. log.Debugf("%+v doesn't exist", params[1])
  55. return "", nil
  56. }
  57. log.Errorf("JsonExtractUnescape : %+v : %s", params[1], err)
  58. return "", nil
  59. }
  60. log.Tracef("extract path %+v", params[1])
  61. return value, nil
  62. }
  63. // func JsonExtract(jsblob string, target string) string {
  64. func JsonExtract(params ...any) (any, error) {
  65. jsblob := params[0].(string)
  66. target := params[1].(string)
  67. if !strings.HasPrefix(target, "[") {
  68. target = strings.ReplaceAll(target, "[", ".[")
  69. }
  70. fullpath := strings.Split(target, ".")
  71. log.Tracef("extract path %+v", fullpath)
  72. return JsonExtractLib(jsblob, fullpath)
  73. }
  74. func jsonExtractType(jsblob string, target string, t jsonparser.ValueType) ([]byte, error) {
  75. if !strings.HasPrefix(target, "[") {
  76. target = strings.ReplaceAll(target, "[", ".[")
  77. }
  78. fullpath := strings.Split(target, ".")
  79. log.Tracef("extract path %+v", fullpath)
  80. value, dataType, _, err := jsonparser.Get(
  81. jsonparser.StringToBytes(jsblob),
  82. fullpath...,
  83. )
  84. if err != nil {
  85. if errors.Is(err, jsonparser.KeyPathNotFoundError) {
  86. log.Debugf("Key %+v doesn't exist", target)
  87. return nil, fmt.Errorf("key %s does not exist", target)
  88. }
  89. log.Errorf("jsonExtractType : %s : %s", target, err)
  90. return nil, fmt.Errorf("jsonExtractType: %s : %w", target, err)
  91. }
  92. if dataType != t {
  93. log.Errorf("jsonExtractType : expected type %s for target %s but found %s", t, target, dataType.String())
  94. return nil, fmt.Errorf("jsonExtractType: expected type %s for target %s but found %s", t, target, dataType.String())
  95. }
  96. return value, nil
  97. }
  98. // func JsonExtractSlice(jsblob string, target string) []interface{} {
  99. func JsonExtractSlice(params ...any) (any, error) {
  100. jsblob := params[0].(string)
  101. target := params[1].(string)
  102. value, err := jsonExtractType(jsblob, target, jsonparser.Array)
  103. if err != nil {
  104. log.Errorf("JsonExtractSlice : %s", err)
  105. return []interface{}(nil), nil
  106. }
  107. s := make([]interface{}, 0)
  108. err = json.Unmarshal(value, &s)
  109. if err != nil {
  110. log.Errorf("JsonExtractSlice: could not convert '%s' to slice: %s", value, err)
  111. return []interface{}(nil), nil
  112. }
  113. return s, nil
  114. }
  115. // func JsonExtractObject(jsblob string, target string) map[string]interface{} {
  116. func JsonExtractObject(params ...any) (any, error) {
  117. jsblob := params[0].(string)
  118. target := params[1].(string)
  119. value, err := jsonExtractType(jsblob, target, jsonparser.Object)
  120. if err != nil {
  121. log.Errorf("JsonExtractObject: %s", err)
  122. return map[string]interface{}(nil), nil
  123. }
  124. s := make(map[string]interface{})
  125. err = json.Unmarshal(value, &s)
  126. if err != nil {
  127. log.Errorf("JsonExtractObject: could not convert '%s' to map[string]interface{}: %s", value, err)
  128. return map[string]interface{}(nil), nil
  129. }
  130. return s, nil
  131. }
  132. // func ToJson(obj interface{}) string {
  133. func ToJson(params ...any) (any, error) {
  134. obj := params[0]
  135. b, err := json.Marshal(obj)
  136. if err != nil {
  137. log.Errorf("ToJson : %s", err)
  138. return "", nil
  139. }
  140. return string(b), nil
  141. }
  142. // Func UnmarshalJSON(jsonBlob []byte, target interface{}) error {
  143. func UnmarshalJSON(params ...any) (any, error) {
  144. jsonBlob := params[0].(string)
  145. target := params[1].(map[string]interface{})
  146. key := params[2].(string)
  147. var out interface{}
  148. err := json.Unmarshal([]byte(jsonBlob), &out)
  149. if err != nil {
  150. log.WithField("line", jsonBlob).Errorf("UnmarshalJSON : %s", err)
  151. return nil, err
  152. }
  153. target[key] = out
  154. return nil, nil
  155. }