@@ -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// // }
182182func WithMaxDepth (n int ) Option {
@@ -904,15 +904,22 @@ func (d *Dumper) getTypeString(t reflect.Type) string {
904904}
905905
906906func (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