-
Notifications
You must be signed in to change notification settings - Fork 155
/
json_manager.go
139 lines (116 loc) · 3.22 KB
/
json_manager.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package jid
import (
"github.com/bitly/go-simplejson"
"github.com/pkg/errors"
"io"
"regexp"
"strconv"
//"strings"
)
type JsonManager struct {
current *simplejson.Json
origin *simplejson.Json
suggestion *Suggestion
}
func NewJsonManager(reader io.Reader) (*JsonManager, error) {
buf, err := io.ReadAll(reader)
if err != nil {
return nil, errors.Wrap(err, "invalid data")
}
j, err2 := simplejson.NewJson(buf)
if err2 != nil {
return nil, errors.Wrap(err2, "invalid json format")
}
json := &JsonManager{
origin: j,
current: j,
suggestion: NewSuggestion(),
}
return json, nil
}
func (jm *JsonManager) Get(q QueryInterface, confirm bool) (string, []string, []string, error) {
json, suggestion, candidates, _ := jm.GetFilteredData(q, confirm)
data, enc_err := json.Encode()
if enc_err != nil {
return "", []string{"", ""}, []string{"", ""}, errors.Wrap(enc_err, "failure json encode")
}
return string(data), suggestion, candidates, nil
}
func (jm *JsonManager) GetPretty(q QueryInterface, confirm bool) (string, []string, []string, error) {
json, suggestion, candidates, _ := jm.GetFilteredData(q, confirm)
s, err := json.EncodePretty()
if err != nil {
return "", []string{"", ""}, []string{"", ""}, errors.Wrap(err, "failure json encode")
}
return string(s), suggestion, candidates, nil
}
func (jm *JsonManager) GetFilteredData(q QueryInterface, confirm bool) (*simplejson.Json, []string, []string, error) {
json := jm.origin
lastKeyword := q.StringGetLastKeyword()
keywords := q.StringGetKeywords()
idx := 0
if l := len(keywords); l == 0 {
return json, []string{"", ""}, []string{}, nil
} else if l > 0 {
idx = l - 1
}
for _, keyword := range keywords[0:idx] {
json, _ = getItem(json, keyword)
}
reg := regexp.MustCompile(`\[[0-9]*$`)
suggest := jm.suggestion.Get(json, lastKeyword)
candidateKeys := jm.suggestion.GetCandidateKeys(json, lastKeyword)
// hash
if len(reg.FindString(lastKeyword)) < 1 {
candidateNum := len(candidateKeys)
if j, exist := getItem(json, lastKeyword); exist && (confirm || candidateNum == 1) {
json = j
candidateKeys = []string{}
if _, err := json.Array(); err == nil {
suggest = jm.suggestion.Get(json, "")
} else {
suggest = []string{"", ""}
}
} else if candidateNum < 1 {
json = j
suggest = jm.suggestion.Get(json, "")
}
}
return json, suggest, candidateKeys, nil
}
func (jm *JsonManager) GetCandidateKeys(q QueryInterface) []string {
return jm.suggestion.GetCandidateKeys(jm.current, q.StringGetLastKeyword())
}
func getItem(json *simplejson.Json, s string) (*simplejson.Json, bool) {
var result *simplejson.Json
var exist bool
re := regexp.MustCompile(`\[([0-9]+)\]`)
matches := re.FindStringSubmatch(s)
if s == "" {
return json, false
}
// Query include [
if len(matches) > 0 {
index, _ := strconv.Atoi(matches[1])
if a, err := json.Array(); err != nil {
exist = false
} else if len(a) < index {
exist = false
}
result = json.GetIndex(index)
} else {
result, exist = json.CheckGet(s)
if result == nil {
result = &simplejson.Json{}
}
}
return result, exist
}
func isEmptyJson(j *simplejson.Json) bool {
switch j.Interface().(type) {
case nil:
return true
default:
return false
}
}