forked from cli/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjsoncolor.go
More file actions
96 lines (84 loc) · 1.74 KB
/
jsoncolor.go
File metadata and controls
96 lines (84 loc) · 1.74 KB
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
package jsoncolor
import (
"encoding/json"
"fmt"
"io"
"strings"
)
const (
colorDelim = "1;38" // bright white
colorKey = "1;34" // bright blue
colorNull = "1;30" // gray
colorString = "32" // green
colorBool = "33" // yellow
)
// Write colorized JSON output parsed from reader
func Write(w io.Writer, r io.Reader, indent string) error {
dec := json.NewDecoder(r)
dec.UseNumber()
var idx int
var stack []json.Delim
for {
t, err := dec.Token()
if err == io.EOF {
break
}
if err != nil {
return err
}
switch tt := t.(type) {
case json.Delim:
switch tt {
case '{', '[':
stack = append(stack, tt)
idx = 0
fmt.Fprintf(w, "\x1b[%sm%s\x1b[m", colorDelim, tt)
if dec.More() {
fmt.Fprint(w, "\n", strings.Repeat(indent, len(stack)))
}
continue
case '}', ']':
stack = stack[:len(stack)-1]
idx = 0
fmt.Fprintf(w, "\x1b[%sm%s\x1b[m", colorDelim, tt)
}
default:
b, err := json.Marshal(tt)
if err != nil {
return err
}
isKey := len(stack) > 0 && stack[len(stack)-1] == '{' && idx%2 == 0
idx++
var color string
if isKey {
color = colorKey
} else if tt == nil {
color = colorNull
} else {
switch t.(type) {
case string:
color = colorString
case bool:
color = colorBool
}
}
if color == "" {
_, _ = w.Write(b)
} else {
fmt.Fprintf(w, "\x1b[%sm%s\x1b[m", color, b)
}
if isKey {
fmt.Fprintf(w, "\x1b[%sm:\x1b[m ", colorDelim)
continue
}
}
if dec.More() {
fmt.Fprintf(w, "\x1b[%sm,\x1b[m\n%s", colorDelim, strings.Repeat(indent, len(stack)))
} else if len(stack) > 0 {
fmt.Fprint(w, "\n", strings.Repeat(indent, len(stack)-1))
} else {
fmt.Fprint(w, "\n")
}
}
return nil
}