Skip to content

Commit 07935f2

Browse files
committed
fix: max depth issues
1 parent 0f7a3fa commit 07935f2

File tree

4 files changed

+326
-23
lines changed

4 files changed

+326
-23
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<a href="https://goreportcard.com/report/github.com/goforj/godump"><img src="https://goreportcard.com/badge/github.com/goforj/godump" alt="Go Report Card"></a>
1212
<a href="https://codecov.io/gh/goforj/godump" ><img src="https://codecov.io/gh/goforj/godump/graph/badge.svg?token=ULUTXL03XC"/></a>
1313
<!-- test-count:embed:start -->
14-
<img src="https://img.shields.io/badge/tests-143-brightgreen" alt="Tests">
14+
<img src="https://img.shields.io/badge/tests-156-brightgreen" alt="Tests">
1515
<!-- test-count:embed:end -->
1616
<a href="https://github.com/avelino/awesome-go?tab=readme-ov-file#parsersencodersdecoders"><img src="https://awesome.re/mentioned-badge-flat.svg" alt="Mentioned in Awesome Go"></a>
1717
</p>
@@ -583,9 +583,9 @@ Param n must be 0 or greater or this will be ignored, and default MaxDepth will
583583
v := map[string]map[string]int{"a": {"b": 1}}
584584
d := godump.NewDumper(godump.WithMaxDepth(1))
585585
d.Dump(v)
586-
// #map[string]int {
586+
// #map[string]map[string]int {
587587
// a => #map[string]int {
588-
// b => ... (max depth)
588+
// b => 1 #int
589589
// }
590590
// }
591591
```

examples/withmaxdepth/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ func main() {
1414
v := map[string]map[string]int{"a": {"b": 1}}
1515
d := godump.NewDumper(godump.WithMaxDepth(1))
1616
d.Dump(v)
17-
// #map[string]int {
17+
// #map[string]map[string]int {
1818
// a => #map[string]int {
19-
// b => ... (max depth)
19+
// b => 1 #int
2020
// }
2121
// }
2222
}

godump.go

Lines changed: 67 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,9 @@ func newDumpState() *dumpState {
174174
// v := map[string]map[string]int{"a": {"b": 1}}
175175
// d := godump.NewDumper(godump.WithMaxDepth(1))
176176
// d.Dump(v)
177-
// // #map[string]int {
177+
// // #map[string]map[string]int {
178178
// // a => #map[string]int {
179-
// // b => ... (max depth)
179+
// // b => 1 #int
180180
// // }
181181
// // }
182182
func WithMaxDepth(n int) Option {
@@ -904,15 +904,22 @@ func (d *Dumper) getTypeString(t reflect.Type) string {
904904
}
905905

906906
func (d *Dumper) printValue(w io.Writer, v reflect.Value, indent int, state *dumpState) {
907-
if indent > d.maxDepth {
908-
fmt.Fprint(w, d.colorize(colorGray, "... (max depth)"))
909-
return
910-
}
911907
if !v.IsValid() {
912908
fmt.Fprint(w, d.colorize(colorGray, "<invalid>"))
913909
return
914910
}
915911

912+
if isNil(v) {
913+
typeStr := d.getTypeString(v.Type())
914+
fmt.Fprintf(w, d.colorize(colorLime, typeStr)+d.colorize(colorGray, "(nil)"))
915+
return
916+
}
917+
918+
if shouldTruncateAtDepth(v, indent, d.maxDepth) {
919+
fmt.Fprint(w, d.colorize(colorGray, "... (max depth)"))
920+
return
921+
}
922+
916923
if s := d.asStringer(v); s != "" {
917924
fmt.Fprint(w, s)
918925
return
@@ -921,18 +928,7 @@ func (d *Dumper) printValue(w io.Writer, v reflect.Value, indent int, state *dum
921928
switch v.Kind() {
922929
case reflect.Chan:
923930
typ := d.colorizer(colorGray, d.getTypeString(v.Type()))
924-
925-
if v.IsNil() {
926-
fmt.Fprint(w, d.colorize(colorGray, fmt.Sprintf("#%s(nil)", typ)))
927-
} else {
928-
fmt.Fprintf(w, "%s(%s)", d.colorize(colorGray, typ), d.colorize(colorCyan, fmt.Sprintf("%#x", v.Pointer())))
929-
}
930-
return
931-
}
932-
933-
if isNil(v) {
934-
typeStr := d.getTypeString(v.Type())
935-
fmt.Fprintf(w, d.colorize(colorLime, typeStr)+d.colorize(colorGray, "(nil)"))
931+
fmt.Fprintf(w, "%s(%s)", d.colorize(colorGray, typ), d.colorize(colorCyan, fmt.Sprintf("%#x", v.Pointer())))
936932
return
937933
}
938934

@@ -1235,3 +1231,56 @@ func (d *Dumper) redactedValue(v reflect.Value) string {
12351231
typeStr := d.getTypeString(v.Type())
12361232
return d.colorize(colorRed, "<redacted>") + d.colorize(colorGray, " #"+typeStr)
12371233
}
1234+
1235+
func isComplexValue(v reflect.Value) bool {
1236+
_, ok := complexBaseKind(v)
1237+
return ok
1238+
}
1239+
1240+
func complexBaseKind(v reflect.Value) (reflect.Kind, bool) {
1241+
if !v.IsValid() {
1242+
return 0, false
1243+
}
1244+
1245+
for v.Kind() == reflect.Interface {
1246+
if v.IsNil() {
1247+
return 0, false
1248+
}
1249+
v = v.Elem()
1250+
}
1251+
1252+
for v.Kind() == reflect.Ptr {
1253+
if v.IsNil() {
1254+
return 0, false
1255+
}
1256+
v = v.Elem()
1257+
}
1258+
1259+
switch v.Kind() {
1260+
case reflect.Struct, reflect.Map, reflect.Slice, reflect.Array:
1261+
return v.Kind(), true
1262+
default:
1263+
return 0, false
1264+
}
1265+
}
1266+
1267+
func shouldTruncateAtDepth(v reflect.Value, indent, maxDepth int) bool {
1268+
if indent > maxDepth && isComplexValue(v) {
1269+
return true
1270+
}
1271+
if indent < maxDepth {
1272+
return false
1273+
}
1274+
1275+
kind, ok := complexBaseKind(v)
1276+
if !ok {
1277+
return false
1278+
}
1279+
1280+
switch kind {
1281+
case reflect.Map, reflect.Slice, reflect.Array:
1282+
return true
1283+
default:
1284+
return false
1285+
}
1286+
}

0 commit comments

Comments
 (0)