Skip to content

Commit c6de7c5

Browse files
committed
fix: fix panic on access unexported field & fix typo
1 parent 6a549b1 commit c6de7c5

3 files changed

Lines changed: 33 additions & 19 deletions

File tree

dump.go

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func dump(v interface{}, depth int) string {
6464

6565
func dumpBool(v bool, depth int) string {
6666
buf := bytes.NewBuffer(nil)
67-
ident(depth, buf)
67+
indent(depth, buf)
6868
buf.WriteString("(bool) ")
6969
if v {
7070
buf.WriteString("true")
@@ -76,7 +76,7 @@ func dumpBool(v bool, depth int) string {
7676

7777
func dumpInt(v interface{}, depth int) string {
7878
buf := bytes.NewBuffer(nil)
79-
ident(depth, buf)
79+
indent(depth, buf)
8080
switch t := v.(type) {
8181
case int:
8282
buf.WriteString("(int) ")
@@ -117,7 +117,7 @@ func dumpInt(v interface{}, depth int) string {
117117

118118
func dumpString(s string, depth int) string {
119119
buf := bytes.NewBuffer(nil)
120-
ident(depth, buf)
120+
indent(depth, buf)
121121
buf.WriteString("(string: ")
122122
buf.WriteString(strconv.FormatInt(int64(len(s)), 10))
123123
buf.WriteString(") ")
@@ -129,7 +129,7 @@ func dumpString(s string, depth int) string {
129129

130130
func dumpFloat(v interface{}, depth int) string {
131131
buf := bytes.NewBuffer(nil)
132-
ident(depth, buf)
132+
indent(depth, buf)
133133
switch t := v.(type) {
134134
case float32:
135135
buf.WriteString("(float32) ")
@@ -145,7 +145,7 @@ func dumpFloat(v interface{}, depth int) string {
145145

146146
func dumpComplex(v interface{}, depth int) string {
147147
buf := bytes.NewBuffer(nil)
148-
ident(depth, buf)
148+
indent(depth, buf)
149149
switch t := v.(type) {
150150
case complex64:
151151
buf.WriteString("(complex64) ")
@@ -176,7 +176,7 @@ func dumpComplex(v interface{}, depth int) string {
176176
func dumpStruct(v reflect.Value, depth int, isPtr bool) string {
177177
typ := v.Type()
178178
buf := bytes.NewBuffer(nil)
179-
ident(depth, buf)
179+
indent(depth, buf)
180180
buf.WriteString("struct(")
181181
if isPtr {
182182
buf.WriteString("*")
@@ -185,14 +185,14 @@ func dumpStruct(v reflect.Value, depth int, isPtr bool) string {
185185
buf.WriteString(") {\n")
186186
for i := 0; i < v.NumField(); i++ {
187187
field := v.Field(i)
188-
ident(depth, buf)
188+
indent(depth, buf)
189189
buf.WriteString("\t")
190-
buf.WriteString(fmt.Sprintf(`["%s"] =>`, typ.Field(i).Name))
190+
buf.WriteString(fmt.Sprintf(`[%s] =>`, sprintfStructField(typ.Field(i).Name)))
191191
buf.WriteString("\n")
192192
if v.Field(i).CanInterface() {
193193
buf.WriteString(dump(field.Interface(), depth+1))
194194
} else {
195-
buf.WriteString(dump(Interface(field), depth+1))
195+
buf.WriteString(dump(Interface(v, i), depth+1))
196196
}
197197
buf.WriteString("\n")
198198
}
@@ -203,31 +203,41 @@ func dumpStruct(v reflect.Value, depth int, isPtr bool) string {
203203
return buf.String()
204204
}
205205

206+
func sprintfStructField(field string) string {
207+
if t := field[0]; t >= 'a' && t <= 'z' {
208+
return fmt.Sprintf("%s:unexported", field)
209+
}
210+
return field
211+
}
212+
206213
// Interface copy the unexported field in a struct, so the value could be `Interfaceable`
207-
func Interface(rv reflect.Value) interface{} {
214+
func Interface(rv reflect.Value, field int) interface{} {
208215
var val interface{}
209216
if rv.CanAddr() {
217+
rv = rv.Field(field)
210218
val = reflect.NewAt(rv.Type(), unsafe.Pointer(rv.UnsafeAddr())).Elem().Interface()
211219
} else {
212220
rv2 := reflect.New(rv.Type()).Elem()
213221
rv2.Set(rv)
214-
val = reflect.NewAt(rv2.Type(), unsafe.Pointer(rv2.UnsafeAddr())).Elem().Interface()
222+
rf := rv2.Field(field)
223+
rf = reflect.NewAt(rf.Type(), unsafe.Pointer(rf.UnsafeAddr())).Elem()
224+
val = rf.Interface()
215225
}
216226
return val
217227
}
218228

219229
func dumpMap(v reflect.Value, depth int) string {
220230
typ := v.Type()
221231
buf := bytes.NewBuffer(nil)
222-
ident(depth, buf)
232+
indent(depth, buf)
223233
buf.WriteString(fmt.Sprintf("map[%s]%s{ \n", typ.Key().String(), typ.Elem().String()))
224234
for _, key := range v.MapKeys() {
225-
ident(depth+1, buf)
235+
indent(depth+1, buf)
226236
buf.WriteString(fmt.Sprintf("[%s] => \n", printMapKey(key)))
227237
buf.WriteString(dump(v.MapIndex(key).Interface(), depth+1))
228238
buf.WriteString("\n")
229239
}
230-
ident(depth, buf)
240+
indent(depth, buf)
231241
buf.WriteString("}")
232242
return buf.String()
233243
}
@@ -244,7 +254,7 @@ func printMapKey(v reflect.Value) string {
244254
func dumpSlice(v reflect.Value, depth int) string {
245255
typ := v.Type()
246256
buf := bytes.NewBuffer(nil)
247-
ident(depth, buf)
257+
indent(depth, buf)
248258
buf.WriteString("slice(")
249259
buf.WriteString(typ.Elem().String())
250260
buf.WriteString(": ")
@@ -253,12 +263,12 @@ func dumpSlice(v reflect.Value, depth int) string {
253263
buf.WriteString(strconv.FormatInt(int64(v.Cap()), 10))
254264
buf.WriteString(") {\n")
255265
for i := 0; i < v.Len(); i++ {
256-
ident(depth+1, buf)
266+
indent(depth+1, buf)
257267
buf.WriteString(fmt.Sprintf("[%d] => \n", i))
258268
buf.WriteString(dump(v.Index(i).Interface(), depth+1))
259269
buf.WriteString("\n")
260270
}
261-
ident(depth, buf)
271+
indent(depth, buf)
262272
buf.WriteString("}")
263273
return buf.String()
264274
}
@@ -267,7 +277,7 @@ func dumpChannel(v interface{}, depth int) string {
267277
buf := bytes.NewBuffer(nil)
268278
typ := reflect.TypeOf(v)
269279
val := reflect.ValueOf(v)
270-
ident(depth, buf)
280+
indent(depth, buf)
271281
buf.WriteString("(")
272282
buf.WriteString(typ.String())
273283
buf.WriteString(": ")
@@ -291,7 +301,7 @@ func dumpPtr(v reflect.Value, depth int) string {
291301
return dump(v.Elem().Interface(), depth)
292302
}
293303

294-
func ident(depth int, writer io.Writer) {
304+
func indent(depth int, writer io.Writer) {
295305
for i := 0; i < depth; i++ {
296306
writer.Write([]byte("\t"))
297307
}

dump_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ func TestDumpStruct(t *testing.T) {
8787
"aaa",
8888
10,
8989
Home{
90+
price: 1,
9091
Address: "aaaaa",
9192
},
9293
}

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/chenqinghe/dump
2+
3+
go 1.14

0 commit comments

Comments
 (0)