-
Notifications
You must be signed in to change notification settings - Fork 376
/
json.go
101 lines (88 loc) · 2.1 KB
/
json.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package extraction
import (
"encoding/json"
"fmt"
"strings"
"github.com/tidwall/gjson"
)
type jsonExtractor struct {
}
var unmarshalJsonCapture = func(result gjson.Result) (interface{}, error) {
bRaw := []byte(result.Raw)
if result.IsObject() {
jObject := map[string]interface{}{}
err := json.Unmarshal(bRaw, &jObject)
if err == nil {
return jObject, err
}
}
if result.IsArray() {
jInterfaceSlice := []interface{}{}
err := json.Unmarshal(bRaw, &jInterfaceSlice)
if err == nil {
return jInterfaceSlice, err
}
}
if result.IsBool() {
jBool := false
err := json.Unmarshal(bRaw, &jBool)
if err == nil {
return jBool, err
}
}
return nil, fmt.Errorf("json could not be unmarshaled")
}
func (je jsonExtractor) extractFromString(source string, jsonPath string) (interface{}, error) {
result := gjson.Get(source, jsonPath)
// path not found
if result.Raw == "" && result.Type == gjson.Null {
return "", fmt.Errorf("no match for the json path: %s", jsonPath)
}
switch result.Type {
case gjson.String:
return result.String(), nil
case gjson.Null:
return nil, nil
case gjson.False:
return false, nil
case gjson.Number:
number := result.String()
if strings.Contains(number, ".") { // float
return result.Float(), nil
}
return result.Int(), nil
case gjson.True:
return true, nil
case gjson.JSON:
return unmarshalJsonCapture(result)
default:
return "", nil
}
}
func (je jsonExtractor) extractFromByteSlice(source []byte, jsonPath string) (interface{}, error) {
result := gjson.GetBytes(source, jsonPath)
// path not found
if result.Raw == "" && result.Type == gjson.Null {
return "", fmt.Errorf("no match for the json path: %s", jsonPath)
}
switch result.Type {
case gjson.String:
return result.String(), nil
case gjson.Null:
return nil, nil
case gjson.False:
return false, nil
case gjson.Number:
number := result.String()
if strings.Contains(number, ".") { // float
return result.Float(), nil
}
return result.Int(), nil
case gjson.True:
return true, nil
case gjson.JSON:
return unmarshalJsonCapture(result)
default:
return "", nil
}
}