summaryrefslogtreecommitdiff
path: root/spew/dump.go
diff options
context:
space:
mode:
authorDave Collins <[email protected]>2013-01-17 18:43:51 -0600
committerDave Collins <[email protected]>2013-01-17 18:43:51 -0600
commit1f81f22357a22a15b37ae60774b1560d2e7209dc (patch)
treee37ef48ff3d523e3eed3cbc9b7512b74e2fdd7d0 /spew/dump.go
parentc5fba05307d6a83b518916402fcf1fc867ce0782 (diff)
Implement support for %#v and %#+v in Formatter.
This commit implements feature request #3. In particular, it allows the formatter to respond to %#v and %#+v. The # flag (%#v) adds type information to the output and the combination of the # and + flags (%#+v) adds both type information and pointer information. This allows the consumer a choice between displaying types, pointer information, or both.
Diffstat (limited to 'spew/dump.go')
-rw-r--r--spew/dump.go19
1 files changed, 15 insertions, 4 deletions
diff --git a/spew/dump.go b/spew/dump.go
index 0416ee0..c635cfe 100644
--- a/spew/dump.go
+++ b/spew/dump.go
@@ -45,6 +45,16 @@ func (d *dumpState) pad() {
d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))
}
+// unpackValue returns values inside of non-nil interfaces when possible.
+// This is useful for data types like structs, arrays, slices, and maps which
+// can contain varying types packed inside an interface.
+func (d *dumpState) unpackValue(v reflect.Value) reflect.Value {
+ if v.Kind() == reflect.Interface && !v.IsNil() {
+ v = v.Elem()
+ }
+ return v
+}
+
// dumpPtr handles formatting of pointers by indirecting them as necessary.
func (d *dumpState) dumpPtr(v reflect.Value) {
// Remove pointers at or below the current depth from map used to detect
@@ -191,7 +201,7 @@ func (d *dumpState) dump(v reflect.Value) {
} else {
numEntries := v.Len()
for i := 0; i < numEntries; i++ {
- d.dump(unpackValue(v.Index(i)))
+ d.dump(d.unpackValue(v.Index(i)))
if i < (numEntries - 1) {
d.w.Write(commaNewlineBytes)
} else {
@@ -223,10 +233,10 @@ func (d *dumpState) dump(v reflect.Value) {
numEntries := v.Len()
keys := v.MapKeys()
for i, key := range keys {
- d.dump(unpackValue(key))
+ d.dump(d.unpackValue(key))
d.w.Write(colonSpaceBytes)
d.ignoreNextPad = true
- d.dump(unpackValue(v.MapIndex(key)))
+ d.dump(d.unpackValue(v.MapIndex(key)))
if i < (numEntries - 1) {
d.w.Write(commaNewlineBytes)
} else {
@@ -253,7 +263,7 @@ func (d *dumpState) dump(v reflect.Value) {
d.w.Write([]byte(vtf.Name))
d.w.Write(colonSpaceBytes)
d.ignoreNextPad = true
- d.dump(unpackValue(v.Field(i)))
+ d.dump(d.unpackValue(v.Field(i)))
if i < (numFields - 1) {
d.w.Write(commaNewlineBytes)
} else {
@@ -289,6 +299,7 @@ func fdump(cs *ConfigState, w io.Writer, a ...interface{}) {
for _, arg := range a {
if arg == nil {
w.Write(interfaceBytes)
+ w.Write(spaceBytes)
w.Write(nilAngleBytes)
w.Write(newlineBytes)
continue