diff --git a/formatter.go b/formatter.go index 8dacda2..a321b4d 100644 --- a/formatter.go +++ b/formatter.go @@ -1,6 +1,7 @@ package pretty import ( + "encoding" "fmt" "io" "reflect" @@ -166,7 +167,20 @@ func (p *printer) printValue(v reflect.Value, showType, quote bool) { io.WriteString(p, t.String()) } writeByte(p, '{') - if nonzero(v) { + printed := false + if v.CanInterface() { + switch vv := v.Interface().(type) { + case fmt.Stringer: + p.fmtString(vv.String(), true) + printed = true + case encoding.TextMarshaler: + if b, err := vv.MarshalText(); err == nil { + p.fmtString(string(b), true) + printed = true + } + } + } + if !printed && nonzero(v) { expand := !canInline(v.Type()) pp := p if expand { diff --git a/formatter_test.go b/formatter_test.go index 1b55ae5..f7aa648 100644 --- a/formatter_test.go +++ b/formatter_test.go @@ -5,6 +5,7 @@ import ( "io" "strings" "testing" + "time" "unsafe" ) @@ -259,3 +260,46 @@ func TestCycle(t *testing.T) { *iv = *i t.Logf("Example long interface cycle:\n%# v", Formatter(i)) } + +func Test(t *testing.T) { + date := time.Date(2006, 1, 2, 3, 4, 5, .678901e9, time.Local) + + s := fmt.Sprintf("%s", Formatter(date)) + + if date.String() != s { + t.Errorf("expected %s, got %s", date.String(), s) + } +} + +type StringerStruct struct{} + +func (t StringerStruct) String() string { + return "StringerStruct" +} + +func TestStringer(t *testing.T) { + s := new(StringerStruct) + + str := fmt.Sprintf("%s", Formatter(s)) + + if s.String() != str { + t.Errorf("expected %s, got %s", s.String(), str) + } +} + +type MarshalTextStruct struct{} + +func (t MarshalTextStruct) MarshalText() ([]byte, error) { + return []byte("MarshalTextStruct"), nil +} + +func TestMarshalTextStruct(t *testing.T) { + s := new(MarshalTextStruct) + + m, _ := s.MarshalText() + str := fmt.Sprintf("%s", Formatter(m)) + + if string(m) != str { + t.Errorf("expected %s, got %s", m, str) + } +}