@@ -33,6 +33,7 @@ const (
3333 defaultMaxItems = 100
3434 defaultMaxStringLen = 100000
3535 defaultMaxStackDepth = 10
36+ defaultShowAllTypes = false
3637 initialCallerSkip = 2
3738)
3839
@@ -84,6 +85,7 @@ type Dumper struct {
8485 maxDepth int
8586 maxItems int
8687 maxStringLen int
88+ showAllTypes bool
8789 writer io.Writer
8890 skippedStackFrames int
8991
@@ -149,13 +151,22 @@ func WithSkipStackFrames(n int) Option {
149151 }
150152}
151153
154+ // WithShowAllTypes enables or disables always showing types for primitives.
155+ func WithShowAllTypes (b bool ) Option {
156+ return func (d * Dumper ) * Dumper {
157+ d .showAllTypes = b
158+ return d
159+ }
160+ }
161+
152162// NewDumper creates a new Dumper with the given options applied.
153163// Defaults are used for any setting not overridden.
154164func NewDumper (opts ... Option ) * Dumper {
155165 d := & Dumper {
156166 maxDepth : defaultMaxDepth ,
157167 maxItems : defaultMaxItems ,
158168 maxStringLen : defaultMaxStringLen ,
169+ showAllTypes : defaultShowAllTypes ,
159170 writer : os .Stdout ,
160171 callerFn : runtime .Caller ,
161172 }
@@ -469,7 +480,17 @@ func (d *Dumper) printValue(tw *tabwriter.Writer, v reflect.Value, indent int, v
469480 case reflect .UnsafePointer :
470481 fmt .Fprint (tw , colorize (colorGray , fmt .Sprintf ("unsafe.Pointer(%#x)" , v .Pointer ())))
471482 case reflect .Map :
472- fmt .Fprintln (tw , "{" )
483+ if d .showAllTypes {
484+ keyType := v .Type ().Key ().Kind ().String ()
485+ valType := v .Type ().Elem ().Kind ().String ()
486+ keyValType := fmt .Sprintf ("#map[%s]%s" , keyType , valType )
487+
488+ fmt .Fprintf (tw , "{ %s" , colorize (colorGray , keyValType ))
489+ fmt .Fprintln (tw )
490+ } else {
491+ fmt .Fprintln (tw , "{" )
492+ }
493+
473494 keys := v .MapKeys ()
474495 for i , key := range keys {
475496 if i >= d .maxItems {
@@ -496,7 +517,13 @@ func (d *Dumper) printValue(tw *tabwriter.Writer, v reflect.Value, indent int, v
496517 }
497518
498519 // Default rendering for other slices/arrays
499- fmt .Fprintln (tw , "[" )
520+ if d .showAllTypes {
521+ fmt .Fprintf (tw , "[ %s" , colorize (colorGray , "#[]" + v .Type ().Elem ().Kind ().String ()))
522+ fmt .Fprintln (tw )
523+ } else {
524+ fmt .Fprintln (tw , "[" )
525+ }
526+
500527 for i := range v .Len () {
501528 if i >= d .maxItems {
502529 indentPrint (tw , indent + 1 , colorize (colorGray , "... (truncated)\n " ))
@@ -515,18 +542,33 @@ func (d *Dumper) printValue(tw *tabwriter.Writer, v reflect.Value, indent int, v
515542 str = string (runes [:d .maxStringLen ]) + "…"
516543 }
517544 fmt .Fprint (tw , colorize (colorYellow , `"` )+ colorize (colorLime , str )+ colorize (colorYellow , `"` ))
545+ if d .showAllTypes {
546+ fmt .Fprint (tw , colorize (colorGray , " #" + v .Type ().String ()))
547+ }
518548 case reflect .Bool :
519549 if v .Bool () {
520550 fmt .Fprint (tw , colorize (colorYellow , "true" ))
521551 } else {
522552 fmt .Fprint (tw , colorize (colorGray , "false" ))
523553 }
554+ if d .showAllTypes {
555+ fmt .Fprint (tw , colorize (colorGray , " #" + v .Type ().String ()))
556+ }
524557 case reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 :
525558 fmt .Fprint (tw , colorize (colorCyan , fmt .Sprint (v .Int ())))
559+ if d .showAllTypes {
560+ fmt .Fprint (tw , colorize (colorGray , " #" + v .Type ().String ()))
561+ }
526562 case reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Uintptr :
527563 fmt .Fprint (tw , colorize (colorCyan , fmt .Sprint (v .Uint ())))
564+ if d .showAllTypes {
565+ fmt .Fprint (tw , colorize (colorGray , " #" + v .Type ().String ()))
566+ }
528567 case reflect .Float32 , reflect .Float64 :
529568 fmt .Fprint (tw , colorize (colorCyan , fmt .Sprintf ("%f" , v .Float ())))
569+ if d .showAllTypes {
570+ fmt .Fprint (tw , colorize (colorGray , " #" + v .Type ().String ()))
571+ }
530572 case reflect .Func :
531573 fmt .Fprint (tw , colorize (colorGray , v .Type ().String ()))
532574 default :
0 commit comments