diff --git a/README.md b/README.md index 4845779..2ade0c1 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ func main() { var d = godump.Dumper{ Indentation: " ", HidePrivateFields: false, + ShowPrimitiveNamedTypes = false Theme: godump.Theme{ String: godump.RGB{R: 138, G: 201, B: 38}, // ... diff --git a/dumper.go b/dumper.go index 2005270..1d411c0 100644 --- a/dumper.go +++ b/dumper.go @@ -105,6 +105,9 @@ type Dumper struct { // The default value is a string of three spaces. Indentation string + // ShowPrimitiveNamedTypes determines whether to show primitive named types. + ShowPrimitiveNamedTypes bool + // HidePrivateFields allows you to optionally hide struct's unexported fields from being printed. HidePrivateFields bool @@ -186,11 +189,9 @@ func (d *Dumper) dump(val reflect.Value, ignoreDepth ...bool) { switch val.Kind() { case reflect.String: - d.buf.WriteString(__(d.Theme.Quotes, `"`) + - __(d.Theme.String, val.String()) + - __(d.Theme.Quotes, `"`)) + d.wrapType(val, __(d.Theme.Quotes, `"`)+__(d.Theme.String, val.String())+__(d.Theme.Quotes, `"`)) case reflect.Bool: - d.buf.WriteString(__(d.Theme.Bool, fmt.Sprintf("%t", val.Bool()))) + d.wrapType(val, __(d.Theme.Bool, fmt.Sprintf("%t", val.Bool()))) case reflect.Slice, reflect.Array: d.dumpSlice(val) case reflect.Map: @@ -207,21 +208,26 @@ func (d *Dumper) dump(val reflect.Value, ignoreDepth ...bool) { case reflect.Pointer: d.dumpPointer(val) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - d.buf.WriteString(__(d.Theme.Number, fmt.Sprint(val))) + d.wrapType(val, __(d.Theme.Number, fmt.Sprint(val))) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - d.buf.WriteString(__(d.Theme.Number, fmt.Sprint(val))) + d.wrapType(val, __(d.Theme.Number, fmt.Sprint(val))) case reflect.Float32, reflect.Float64: - d.buf.WriteString(__(d.Theme.Number, fmt.Sprint(val))) + d.wrapType(val, __(d.Theme.Number, fmt.Sprint(val))) case reflect.Complex64, reflect.Complex128: - d.buf.WriteString(__(d.Theme.Number, fmt.Sprint(val))) + d.wrapType(val, __(d.Theme.Number, fmt.Sprint(val))) case reflect.Uintptr: - d.buf.WriteString(__(d.Theme.Number, fmt.Sprintf("0x%x", val.Uint()))) + d.wrapType(val, __(d.Theme.Number, fmt.Sprintf("0x%x", val.Uint()))) case reflect.Invalid: d.buf.WriteString(__(d.Theme.Nil, "nil")) case reflect.Interface: d.dump(val.Elem(), true) case reflect.UnsafePointer: - d.buf.WriteString(__(d.Theme.UnsafePointer, fmt.Sprintf("unsafe.Pointer(0x%x)", uintptr(val.UnsafePointer())))) + d.buf.WriteString( + __(d.Theme.Types, val.Type().String()) + + __(d.Theme.Braces, "(") + + __(d.Theme.UnsafePointer, fmt.Sprintf("0x%x", uintptr(val.UnsafePointer()))) + + __(d.Theme.Braces, ")"), + ) } } @@ -374,3 +380,13 @@ func isPrimitive(val reflect.Value) bool { } } } + +func (d *Dumper) wrapType(v reflect.Value, str string) { + if d.ShowPrimitiveNamedTypes { + if t := v.Type(); t.PkgPath() != "" { + str = __(d.Theme.Types, t.String()) + __(d.Theme.Braces, "(") + str + __(d.Theme.Braces, ")") + } + } + + d.buf.WriteString(str) +} diff --git a/dumper_test.go b/dumper_test.go index 5673d43..0e30b2c 100644 --- a/dumper_test.go +++ b/dumper_test.go @@ -58,6 +58,8 @@ func TestCanDumpPrimitives(t *testing.T) { type Chan1Type <-chan struct{} type Chan2Type chan<- struct{} + type UnsafePointer unsafe.Pointer + type Node struct { Int int Int8 int8 @@ -199,8 +201,9 @@ func TestCanDumpPrimitives(t *testing.T) { BufferedChan chan struct{} - UnsafePointer1 unsafe.Pointer - UnsafePointer2 *unsafe.Pointer + UnsafePointer1 unsafe.Pointer + UnsafePointer2 *unsafe.Pointer + NamedUnsafePointer UnsafePointer } node := Node{ @@ -246,7 +249,8 @@ func TestCanDumpPrimitives(t *testing.T) { Nil: nil, - UnsafePointer1: nil, + UnsafePointer1: nil, + NamedUnsafePointer: nil, BufferedChan: make(chan struct{}, 255), } @@ -346,6 +350,117 @@ func TestCanDumpPrimitives(t *testing.T) { checkFromFeed(t, []byte(result), "./testdata/primitives.txt") } +func TestCanDumpNamedPrimitives(t *testing.T) { + type IntType int + type Int8Type int8 + type Int16Type int16 + type Int32Type int32 + type Int64Type int64 + type UintType uint + type Uint8Type uint8 + type Uint16Type uint16 + type Uint32Type uint32 + type Uint64Type uint64 + type Float32Type float32 + type Float64Type float64 + type Complex64Type complex64 + type Complex128Type complex128 + type Bool1Type bool + type Bool2Type bool + type StringType string + type UintptrType uintptr + + type Node struct { + Int IntType + Int8 Int8Type + Int16 Int16Type + Int32 Int32Type + Int64 Int64Type + Uint UintType + Uint8 Uint8Type + Uint16 Uint16Type + Uint32 Uint32Type + Uint64 Uint64Type + Float32 Float32Type + Float64 Float64Type + Complex64 Complex64Type + Complex128 Complex128Type + Bool1 Bool1Type + Bool2 Bool2Type + String StringType + + Uintptr UintptrType + + PtrInt *IntType + PtrInt8 *Int8Type + PtrInt16 *Int16Type + PtrInt32 *Int32Type + PtrInt64 *Int64Type + PtrUint *UintType + PtrUint8 *Uint8Type + PtrUint16 *Uint16Type + PtrUint32 *Uint32Type + PtrUint64 *Uint64Type + PtrFloat32 *Float32Type + PtrFloat64 *Float64Type + PtrComplex64 *Complex64Type + PtrComplex128 *Complex128Type + PtrBool1 *Bool1Type + PtrBool2 *Bool2Type + PtrString *StringType + + PtrUintptr *UintptrType + } + + node := Node{ + Int: IntType(123), + Int8: Int8Type(-45), + Int16: Int16Type(6789), + Int32: Int32Type(-987), + Int64: Int64Type(3849876543247876432), + Uint: UintType(837), + Uint8: Uint8Type(38), + Uint16: Uint16Type(3847), + Uint32: Uint32Type(9843), + Uint64: Uint64Type(2834), + Float32: Float32Type(123.475), + Float64: Float64Type(-12345.09876), + Complex64: Complex64Type(12.987i), + Complex128: Complex128Type(-473i), + Bool1: Bool1Type(true), + Bool2: Bool2Type(false), + String: StringType("foo bar"), + + Uintptr: UintptrType(1234567890), + } + + node.PtrInt = &node.Int + node.PtrInt8 = &node.Int8 + node.PtrInt16 = &node.Int16 + node.PtrInt32 = &node.Int32 + node.PtrInt64 = &node.Int64 + node.PtrUint = &node.Uint + node.PtrUint8 = &node.Uint8 + node.PtrUint16 = &node.Uint16 + node.PtrUint32 = &node.Uint32 + node.PtrUint64 = &node.Uint64 + node.PtrFloat32 = &node.Float32 + node.PtrFloat64 = &node.Float64 + node.PtrComplex64 = &node.Complex64 + node.PtrComplex128 = &node.Complex128 + node.PtrBool1 = &node.Bool1 + node.PtrBool2 = &node.Bool2 + node.PtrString = &node.String + + node.PtrUintptr = &node.Uintptr + + var d godump.Dumper + d.ShowPrimitiveNamedTypes = true + result := d.Sprint(node) + + checkFromFeed(t, []byte(result), "./testdata/named-primitives.txt") +} + func TestCanDumpStructs(t *testing.T) { type Number int diff --git a/testdata/named-primitives.txt b/testdata/named-primitives.txt new file mode 100644 index 0000000..1710f19 --- /dev/null +++ b/testdata/named-primitives.txt @@ -0,0 +1,38 @@ +godump_test.Node { + Int: godump_test.IntType(123), + Int8: godump_test.Int8Type(-45), + Int16: godump_test.Int16Type(6789), + Int32: godump_test.Int32Type(-987), + Int64: godump_test.Int64Type(3849876543247876432), + Uint: godump_test.UintType(837), + Uint8: godump_test.Uint8Type(38), + Uint16: godump_test.Uint16Type(3847), + Uint32: godump_test.Uint32Type(9843), + Uint64: godump_test.Uint64Type(2834), + Float32: godump_test.Float32Type(123.475), + Float64: godump_test.Float64Type(-12345.09876), + Complex64: godump_test.Complex64Type((0+12.987i)), + Complex128: godump_test.Complex128Type((0-473i)), + Bool1: godump_test.Bool1Type(true), + Bool2: godump_test.Bool2Type(false), + String: godump_test.StringType("foo bar"), + Uintptr: godump_test.UintptrType(0x499602d2), + PtrInt: &godump_test.IntType(123), + PtrInt8: &godump_test.Int8Type(-45), + PtrInt16: &godump_test.Int16Type(6789), + PtrInt32: &godump_test.Int32Type(-987), + PtrInt64: &godump_test.Int64Type(3849876543247876432), + PtrUint: &godump_test.UintType(837), + PtrUint8: &godump_test.Uint8Type(38), + PtrUint16: &godump_test.Uint16Type(3847), + PtrUint32: &godump_test.Uint32Type(9843), + PtrUint64: &godump_test.Uint64Type(2834), + PtrFloat32: &godump_test.Float32Type(123.475), + PtrFloat64: &godump_test.Float64Type(-12345.09876), + PtrComplex64: &godump_test.Complex64Type((0+12.987i)), + PtrComplex128: &godump_test.Complex128Type((0-473i)), + PtrBool1: &godump_test.Bool1Type(true), + PtrBool2: &godump_test.Bool2Type(false), + PtrString: &godump_test.StringType("foo bar"), + PtrUintptr: &godump_test.UintptrType(0x499602d2), +} \ No newline at end of file diff --git a/testdata/primitives.txt b/testdata/primitives.txt index 964e71f..fc9cb75 100644 --- a/testdata/primitives.txt +++ b/testdata/primitives.txt @@ -121,4 +121,5 @@ godump_test.Node { BufferedChan: chan struct {}<255>, UnsafePointer1: unsafe.Pointer(0x0), UnsafePointer2: &unsafe.Pointer(0x7b), + NamedUnsafePointer: godump_test.UnsafePointer(0x0), } \ No newline at end of file