Skip to content

Commit

Permalink
feat: handle Stringer interface
Browse files Browse the repository at this point in the history
Signed-off-by: francois  samin <[email protected]>
  • Loading branch information
fsamin committed Nov 30, 2020
1 parent 896154b commit 5c3acfb
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 5 deletions.
42 changes: 40 additions & 2 deletions dump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import (
"fmt"
"os"
"testing"
"time"

"github.com/spf13/viper"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/fsamin/go-dump"
)
Expand All @@ -30,7 +32,6 @@ func TestDumpStruct(t *testing.T) {
T.B: foo bar
`
assert.Equal(t, expected, out.String())

}

func TestDumpStructWithOutPrefix(t *testing.T) {
Expand Down Expand Up @@ -438,7 +439,7 @@ func TestWithDetailedStruct(t *testing.T) {
enc.ExtraFields.Len = true
res, _ := enc.Sdump(a)
t.Log(res)
assert.Equal(t, `T: {23 foo bar}
assert.Equal(t, `T: {"A":23,"B":"foo bar"}
T.A: 23
T.B: foo bar
T.__Len__: 2
Expand Down Expand Up @@ -675,3 +676,40 @@ func TestDetailArray(t *testing.T) {
t.Logf("shoud be an array: %T %v", m["writers"], m["writers"])
assert.NotEmpty(t, m["writers"])
}

func Test_DumpTime(t *testing.T) {
m := map[string]interface{}{
"string": "foobar",
"date": time.Date(2020, time.November, 29, 10, 00, 00, 00, time.Local),
"dates": []time.Time{time.Date(2020, time.November, 29, 10, 00, 00, 00, time.Local)},
}

result, err := dump.ToStringMap(m)
require.NoError(t, err)
t.Log(result)

require.NotZero(t, result["date"])
require.NotZero(t, result["date.Time"])
require.NotZero(t, result["dates.dates0"])

}

func Test_DumpTimeWithDetailledStruct(t *testing.T) {
m := map[string]interface{}{
"string": "foobar",
"date": time.Date(2020, time.November, 29, 10, 00, 00, 00, time.Local),
"dates": []time.Time{time.Date(2020, time.November, 29, 10, 00, 00, 00, time.Local)},
}

dmp := dump.NewDefaultEncoder()
dmp.ExtraFields.DetailedStruct = true
dmp.ExtraFields.DetailedMap = true
dmp.ExtraFields.DetailedArray = true
result, err := dmp.ToStringMap(m)
t.Log(result)
require.NoError(t, err)
require.NotZero(t, result["date"])
require.NotZero(t, result["date.Time"])
require.NotZero(t, result["dates.dates0"])

}
31 changes: 28 additions & 3 deletions encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ func (e *Encoder) fDumpArray(w map[string]interface{}, i interface{}, roots []st

for i := 0; i < v.Len(); i++ {
var l string
//croots := roots
var croots []string
if len(roots) > 0 {
l = roots[len(roots)-1:][0]
Expand All @@ -211,6 +210,13 @@ func (e *Encoder) fDumpArray(w map[string]interface{}, i interface{}, roots []st
croots = append(roots, fmt.Sprintf("%s%d", l, i))
}
f := v.Index(i)

stringer, ok := f.Interface().(fmt.Stringer)
if ok {
k := strings.Join(sliceFormat(croots, e.Formatters), e.Separator)
w[k] = stringer.String()
}

if err := e.fdumpInterface(w, f.Interface(), croots); err != nil {
return err
}
Expand All @@ -235,8 +241,15 @@ func (e *Encoder) fDumpMap(w map[string]interface{}, i interface{}, roots []stri

f := valueFromInterface(value.Interface())

if validAndNotEmpty(f) && f.Type().Kind() == reflect.Struct && !e.DisableTypePrefix {
croots = append(croots, f.Type().Name())
if validAndNotEmpty(f) && f.Type().Kind() == reflect.Struct {
stringer, ok := value.Interface().(fmt.Stringer)
if ok {
structKey := strings.Join(sliceFormat(croots, e.Formatters), e.Separator)
w[structKey] = stringer.String()
}
if !e.DisableTypePrefix {
croots = append(croots, f.Type().Name())
}
}

if err := e.fdumpInterface(w, value.Interface(), croots); err != nil {
Expand Down Expand Up @@ -270,6 +283,7 @@ func (e *Encoder) fdumpStruct(w map[string]interface{}, s reflect.Value, roots [
}
}

var atLeastOneField bool
for i := 0; i < s.NumField(); i++ {
k := reflect.ValueOf(i).Kind()
if k == reflect.Ptr && reflect.ValueOf(i).IsNil() {
Expand All @@ -278,17 +292,28 @@ func (e *Encoder) fdumpStruct(w map[string]interface{}, s reflect.Value, roots [
}
k := strings.Join(sliceFormat(roots, e.Formatters), e.Separator)
w[k] = ""
atLeastOneField = true
continue
}

if !s.Field(i).CanInterface() {
continue
}
croots := append(roots, s.Type().Field(i).Name)
atLeastOneField = true
if err := e.fdumpInterface(w, s.Field(i).Interface(), croots); err != nil {
return err
}
}

if !atLeastOneField {
stringer, ok := s.Interface().(fmt.Stringer)
if ok {
structKey := strings.Join(sliceFormat(roots, e.Formatters), e.Separator)
w[structKey] = stringer.String()
}
}

return nil
}

Expand Down

0 comments on commit 5c3acfb

Please sign in to comment.