Skip to content

Commit 20eec23

Browse files
committed
* rewrite printer_json.go
1 parent 03947ad commit 20eec23

File tree

1 file changed

+110
-46
lines changed

1 file changed

+110
-46
lines changed

Diff for: etcdctl/ctlv3/command/printer_json.go

+110-46
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ package command
1717
import (
1818
"encoding/json"
1919
"fmt"
20-
"os"
21-
"slices"
2220

21+
pb "go.etcd.io/etcd/api/v3/etcdserverpb"
2322
v3 "go.etcd.io/etcd/client/v3"
2423
)
2524

@@ -35,65 +34,130 @@ func newJSONPrinter(isHex bool) printer {
3534
}
3635
}
3736

38-
func (p *jsonPrinter) EndpointHealth(r []epHealth) { p.printJSON(r) }
39-
func (p *jsonPrinter) EndpointStatus(r []epStatus) { p.printJSON(r) }
40-
func (p *jsonPrinter) EndpointHashKV(r []epHashKV) { p.printJSON(r) }
37+
type (
38+
HexResponseHeader pb.ResponseHeader
39+
HexMember pb.Member
40+
)
41+
42+
func (h *HexResponseHeader) MarshalJSON() ([]byte, error) {
43+
type Alias pb.ResponseHeader
44+
45+
return json.Marshal(&struct {
46+
ClusterID string `json:"cluster_id"`
47+
MemberID string `json:"member_id"`
48+
Alias
49+
}{
50+
ClusterID: fmt.Sprintf("%x", h.ClusterId),
51+
MemberID: fmt.Sprintf("%x", h.MemberId),
52+
Alias: (Alias)(*h),
53+
})
54+
}
4155

42-
func (p *jsonPrinter) MemberAdd(r v3.MemberAddResponse) { p.printJSON(r) }
43-
func (p *jsonPrinter) MemberList(r v3.MemberListResponse) { p.printJSON(r) }
56+
func (m *HexMember) MarshalJSON() ([]byte, error) {
57+
type Alias pb.Member
58+
59+
return json.Marshal(&struct {
60+
ID string `json:"ID"`
61+
Alias
62+
}{
63+
ID: fmt.Sprintf("%x", m.ID),
64+
Alias: (Alias)(*m),
65+
})
66+
}
67+
68+
func (p *jsonPrinter) MemberAdd(r v3.MemberAddResponse) { p.printJSON(r) }
69+
func (p *jsonPrinter) MemberList(r v3.MemberListResponse) { p.printJSON(r) }
70+
func (p *jsonPrinter) MemberPromote(id uint64, r v3.MemberPromoteResponse) { p.printJSON(r) }
71+
func (p *jsonPrinter) MemberRemove(id uint64, r v3.MemberRemoveResponse) { p.printJSON(r) }
72+
func (p *jsonPrinter) MemberUpdate(id uint64, r v3.MemberUpdateResponse) { p.printJSON(r) }
4473

4574
func printJSON(v any) {
46-
b, err := json.Marshal(v)
47-
if err != nil {
48-
fmt.Fprintf(os.Stderr, "%v\n", err)
49-
return
50-
}
75+
b, _ := json.Marshal(v)
5176
fmt.Println(string(b))
5277
}
5378

5479
func (p *jsonPrinter) printJSON(v any) {
55-
b, err := json.Marshal(v)
56-
if err != nil {
57-
fmt.Fprintf(os.Stderr, "%v\n", err)
58-
return
59-
}
80+
var data any
6081

6182
if !p.isHex {
62-
fmt.Println(string(b))
83+
printJSON(v)
6384
return
6485
}
6586

66-
var data any
67-
if err = json.Unmarshal(b, &data); err != nil {
68-
fmt.Fprintf(os.Stderr, "%v\n", err)
69-
return
70-
}
87+
switch r := v.(type) {
88+
case v3.MemberAddResponse:
89+
type Alias v3.MemberAddResponse
7190

72-
convertFieldsToHex(data)
73-
b, err = json.Marshal(data)
74-
if err != nil {
75-
fmt.Fprintf(os.Stderr, "%v\n", err)
76-
return
77-
}
78-
fmt.Println(string(b))
79-
}
91+
data = &struct {
92+
Header *HexResponseHeader `json:"header"`
93+
Member *HexMember `json:"member"`
94+
Members []*HexMember `json:"members"`
95+
*Alias
96+
}{
97+
Header: (*HexResponseHeader)(r.Header),
98+
Member: (*HexMember)(r.Member),
99+
Members: toHexMembers(r.Members),
100+
Alias: (*Alias)(&r),
101+
}
102+
case v3.MemberListResponse:
103+
type Alias v3.MemberListResponse
104+
105+
data = &struct {
106+
Header *HexResponseHeader `json:"header"`
107+
Members []*HexMember `json:"members"`
108+
*Alias
109+
}{
110+
Header: (*HexResponseHeader)(r.Header),
111+
Members: toHexMembers(r.Members),
112+
Alias: (*Alias)(&r),
113+
}
114+
case v3.MemberPromoteResponse:
115+
type Alias v3.MemberPromoteResponse
80116

81-
func convertFieldsToHex(data any) {
82-
keysToConvert := []string{"cluster_id", "member_id", "ID", "leader"}
83-
84-
switch v := data.(type) {
85-
case map[string]any:
86-
for key, val := range v {
87-
if slices.Contains(keysToConvert, key) {
88-
if num, ok := val.(float64); ok {
89-
v[key] = fmt.Sprintf("%x", uint64(num))
90-
}
91-
}
92-
convertFieldsToHex(val)
117+
data = &struct {
118+
Header *HexResponseHeader `json:"header"`
119+
Members []*HexMember `json:"members"`
120+
*Alias
121+
}{
122+
Header: (*HexResponseHeader)(r.Header),
123+
Members: toHexMembers(r.Members),
124+
Alias: (*Alias)(&r),
93125
}
94-
case []any:
95-
for _, item := range v {
96-
convertFieldsToHex(item)
126+
case v3.MemberRemoveResponse:
127+
type Alias v3.MemberRemoveResponse
128+
129+
data = &struct {
130+
Header *HexResponseHeader `json:"header"`
131+
Members []*HexMember `json:"members"`
132+
*Alias
133+
}{
134+
Header: (*HexResponseHeader)(r.Header),
135+
Members: toHexMembers(r.Members),
136+
Alias: (*Alias)(&r),
137+
}
138+
case v3.MemberUpdateResponse:
139+
type Alias v3.MemberUpdateResponse
140+
141+
data = &struct {
142+
Header *HexResponseHeader `json:"header"`
143+
Members []*HexMember `json:"members"`
144+
*Alias
145+
}{
146+
Header: (*HexResponseHeader)(r.Header),
147+
Members: toHexMembers(r.Members),
148+
Alias: (*Alias)(&r),
97149
}
150+
default:
151+
data = v
152+
}
153+
154+
printJSON(data)
155+
}
156+
157+
func toHexMembers(members []*pb.Member) []*HexMember {
158+
hexMembers := make([]*HexMember, len(members))
159+
for i, member := range members {
160+
hexMembers[i] = (*HexMember)(member)
98161
}
162+
return hexMembers
99163
}

0 commit comments

Comments
 (0)