forked from bcicen/jstream
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
90 lines (74 loc) · 1.69 KB
/
main.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
package main
import (
"encoding/json"
"flag"
"fmt"
"os"
"github.com/bcicen/jstream"
)
var (
depthFlag = flag.Int("d", 0, "emit values at depth <int>")
kvFlag = flag.Bool("kv", false, "output key value pairs. default behavior is to emit only JSON object values.")
verboseFlag = flag.Bool("v", false, "output depth and offset details for each value")
helpFlag = flag.Bool("h", false, "display this help dialog")
)
func exitErr(err error) {
fmt.Fprintf(os.Stderr, "[\033[31merror\033[0m] %s", err)
os.Exit(1)
}
func printVal(mv *jstream.MetaValue) {
b, err := json.Marshal(mv.Value)
if err != nil {
exitErr(err)
}
s := string(b)
var label string
switch mv.Value.(type) {
case []interface{}:
label = "array "
case float64:
label = "float "
case jstream.KV:
label = "kv "
case string:
label = "string "
case map[string]interface{}:
label = "object "
}
if *verboseFlag {
end := mv.Offset + mv.Length
fmt.Printf("%d\t%03d\t%03d\t%s| %s\n", mv.Depth, mv.Offset, end, label, s)
return
}
fmt.Printf("%s| %s\n", label, s)
}
func main() {
flag.Parse()
if *helpFlag {
help()
os.Exit(0)
}
if *verboseFlag {
fmt.Println("depth\tstart\tend\ttype | value\n")
}
decoder := jstream.NewDecoder(os.Stdin, *depthFlag)
if *kvFlag {
decoder = decoder.EmitKV()
}
for mv := range decoder.Stream() {
printVal(mv)
}
if err := decoder.Err(); err != nil {
exitErr(err)
}
}
var helpMsg = `jstream - stream parsed values from JSON
usage: jstream [options]
options:
-d <n> emit values at depth n. if n < 0, all values will be emitted
-v output depth and offset details for each value
-h display this help dialog
`
func help() {
fmt.Println(helpMsg)
}