forked from davyxu/tabtoy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
json.go
180 lines (120 loc) · 2.97 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
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package printer
import (
"strconv"
"github.com/BobWong/tabtoy/util"
"github.com/BobWong/tabtoy/v2/i18n"
"github.com/BobWong/tabtoy/v2/model"
)
func valueWrapperJson(t model.FieldType, node *model.Node) string {
switch t {
case model.FieldType_String:
return util.StringEscape(node.Value)
case model.FieldType_Enum:
return strconv.Itoa(int(node.EnumValue))
}
return node.Value
}
type jsonPrinter struct {
}
func (self *jsonPrinter) Run(g *Globals) *Stream {
bf := NewStream()
bf.Printf("{\n")
bf.Printf(" \"Tool\": \"github.com/davyxu/tabtoy\",\n")
bf.Printf(" \"Version\": \"%s\",\n", g.Version)
for tabIndex, tab := range g.Tables {
if !tab.LocalFD.MatchTag(".json") {
log.Infof("%s: %s", i18n.String(i18n.Printer_IgnoredByOutputTag), tab.Name())
continue
}
if tabIndex > 0 {
bf.Printf(", \n")
}
if !printTableJson(bf, tab) {
return nil
}
}
bf.Printf("}")
return bf
}
func printTableJson(bf *Stream, tab *model.Table) bool {
bf.Printf(" \"%s\":[\n", tab.LocalFD.Name)
// 遍历每一行
for rIndex, r := range tab.Recs {
bf.Printf(" { ")
var hasWriteColumn bool
// 遍历每一列
for rootFieldIndex, node := range r.Nodes {
if node.SugguestIgnore {
continue
}
if hasWriteColumn && rootFieldIndex > 0 {
bf.Printf(", ")
hasWriteColumn = false
}
if node.IsRepeated {
bf.Printf("\"%s\":[ ", node.Name)
} else {
bf.Printf("\"%s\": ", node.Name)
}
// 普通值
if node.Type != model.FieldType_Struct {
if node.IsRepeated {
// repeated 值序列
for arrIndex, valueNode := range node.Child {
bf.Printf("%s", valueWrapperJson(node.Type, valueNode))
// 多个值分割
if arrIndex < len(node.Child)-1 {
bf.Printf(", ")
}
}
} else {
// 单值
valueNode := node.Child[0]
bf.Printf("%s", valueWrapperJson(node.Type, valueNode))
}
} else {
// 遍历repeated的结构体
for structIndex, structNode := range node.Child {
// 结构体开始
bf.Printf("{ ")
var hasWriteField bool
// 遍历一个结构体的字段
for structFieldIndex, fieldNode := range structNode.Child {
if fieldNode.SugguestIgnore {
continue
}
if hasWriteField && structFieldIndex > 0 {
bf.Printf(", ")
hasWriteField = false
}
// 值节点总是在第一个
valueNode := fieldNode.Child[0]
bf.Printf("\"%s\": %s", fieldNode.Name, valueWrapperJson(fieldNode.Type, valueNode))
hasWriteField = true
}
// 结构体结束
bf.Printf(" }")
// 多个结构体分割
if structIndex < len(node.Child)-1 {
bf.Printf(", ")
}
}
}
if node.IsRepeated {
bf.Printf(" ]")
}
// 根字段分割
hasWriteColumn = true
}
bf.Printf(" }")
if rIndex < len(tab.Recs)-1 {
bf.Printf(",")
}
bf.Printf("\n")
}
bf.Printf(" ]")
return true
}
func init() {
RegisterPrinter("json", &jsonPrinter{})
}