-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
json.go
100 lines (91 loc) · 1.83 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
package utils
import (
"encoding/json"
"fmt"
"io"
"strings"
)
type state struct {
isObject bool
isArray bool
arrayIndex int
objectKey string
parentState *state
}
func stateKey(s *state) string {
k := ""
if s.parentState != nil {
k = stateKey(s.parentState)
}
if s.isObject {
return fmt.Sprintf("%s.%s", k, s.objectKey)
} else if s.isArray {
return fmt.Sprintf("%s.[%d]", k, s.arrayIndex)
} else {
return k
}
}
func printValue(token json.Token) {
}
func JSONPath(out io.Writer, src io.Reader, colorize bool) {
dec := json.NewDecoder(src)
dec.UseNumber()
s := &state{}
postEmit := func() {
if s.isObject {
s.objectKey = ""
} else if s.isArray {
s.arrayIndex++
}
}
color := func(c string, t interface{}) string {
if colorize {
return fmt.Sprintf("\033[%sm%s\033[m", c, t)
} else if tt, ok := t.(string); ok {
return tt
} else {
return fmt.Sprintf("%s", t)
}
}
for {
token, err := dec.Token()
if err == io.EOF {
break
} else if err != nil {
panic(err)
}
if delim, ok := token.(json.Delim); ok {
switch delim {
case '{':
s = &state{isObject: true, parentState: s}
case '[':
s = &state{isArray: true, parentState: s}
case '}', ']':
s = s.parentState
postEmit()
default:
panic("unknown delim")
}
} else {
if s.isObject && s.objectKey == "" {
s.objectKey = token.(string)
} else {
k := stateKey(s)
fmt.Fprintf(out, "%s\t", color("0;36", k))
switch tt := token.(type) {
case string:
fmt.Fprintf(out, "%s\n", strings.Replace(tt, "\n", "\\n", -1))
case json.Number:
fmt.Fprintf(out, "%s\n", color("0;35", tt))
case nil:
fmt.Fprintf(out, "\n")
case bool:
fmt.Fprintf(out, "%s\n", color("1;33", fmt.Sprintf("%v", tt)))
default:
panic("unknown type")
}
postEmit()
}
}
}
}