-
Notifications
You must be signed in to change notification settings - Fork 0
/
jsonviz.go
124 lines (104 loc) · 2.56 KB
/
jsonviz.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
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"os"
ui "github.com/gizak/termui/v3"
"github.com/gizak/termui/v3/widgets"
)
type nodeValue struct {
Key string
Value interface{}
}
var (
rootStyle = ui.NewStyle(ui.ColorGreen)
keyStyle = ui.NewStyle(ui.ColorGreen)
valueStyle = ui.NewStyle(ui.ColorWhite)
selectedStyle = ui.NewStyle(ui.ColorYellow, ui.ColorClear, ui.ModifierBold) // Correctly apply style with modifiers
)
func (nv nodeValue) String() string {
if nv.Key == "root" {
return fmt.Sprintf("[%s](fg:green)", nv.Key)
}
switch v := nv.Value.(type) {
case string, float64, bool, int:
return fmt.Sprintf("[%s: %v](fg:white)", nv.Key, v)
default:
return fmt.Sprintf("[%s](fg:green)", nv.Key)
}
}
func parseJSONToTree(key string, data interface{}) *widgets.TreeNode {
node := &widgets.TreeNode{
Value: nodeValue{Key: key},
}
switch v := data.(type) {
case map[string]interface{}:
children := []*widgets.TreeNode{}
for k, val := range v {
child := parseJSONToTree(k, val)
children = append(children, child)
}
node.Nodes = children
case []interface{}:
children := []*widgets.TreeNode{}
for i, val := range v {
child := parseJSONToTree(fmt.Sprintf("%s[%d]", key, i), val)
children = append(children, child)
}
node.Nodes = children
default:
node.Value = nodeValue{Key: key, Value: v}
}
return node
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: jsonviz [filename]")
os.Exit(1)
}
filename := os.Args[1]
fmt.Println("Initializing UI... Press CTRL+C to exit.")
if err := ui.Init(); err != nil {
log.Fatalf("failed to initialize termui: %v", err)
}
defer ui.Close()
jsonFile, err := os.Open(filename)
if err != nil {
log.Fatalf("failed to open JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, _ := io.ReadAll(jsonFile)
var result interface{}
json.Unmarshal(byteValue, &result)
root := parseJSONToTree("root", result)
tree := widgets.NewTree()
tree.Title = "JSON Visualizer (Press CTRL+C to exit)"
tree.TextStyle = ui.NewStyle(ui.ColorWhite)
tree.SelectedRowStyle = selectedStyle
tree.WrapText = false
tree.SetNodes([]*widgets.TreeNode{root})
x, y := ui.TerminalDimensions()
tree.SetRect(0, 0, x, y)
ui.Render(tree)
uiEvents := ui.PollEvents()
for {
e := <-uiEvents
switch e.ID {
case "q", "<C-c>":
return
case "j", "<Down>":
tree.ScrollDown()
case "k", "<Up>":
tree.ScrollUp()
case "<Enter>":
tree.ToggleExpand()
case "<Resize>":
x, y := ui.TerminalDimensions()
tree.SetRect(0, 0, x, y)
ui.Render(tree)
}
ui.Render(tree)
}
}