Skip to content

Commit

Permalink
feat: json dump (#16)
Browse files Browse the repository at this point in the history
* feat: dump json hidden in string value
  • Loading branch information
sguiheux authored and fsamin committed Feb 23, 2018
1 parent e10084d commit 7ae1b0f
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 8 deletions.
56 changes: 50 additions & 6 deletions encoder.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dump

import (
"encoding/json"
"fmt"
"io"
"reflect"
Expand All @@ -17,6 +18,7 @@ type Encoder struct {
Type bool
DetailedStruct bool
DetailedMap bool
DeepJSON bool
}
writer io.Writer
}
Expand Down Expand Up @@ -103,11 +105,6 @@ func (e *Encoder) fdumpInterface(w map[string]interface{}, i interface{}, roots
return err
}
case reflect.Array, reflect.Slice:
if e.ExtraFields.Type {
nodeType := append(roots, "__Type__")
nodeTypeFormatted := strings.Join(sliceFormat(nodeType, e.Formatters), ".")
w[nodeTypeFormatted] = "Array"
}
if err := e.fDumpArray(w, i, roots); err != nil {
return err
}
Expand All @@ -124,12 +121,59 @@ func (e *Encoder) fdumpInterface(w map[string]interface{}, i interface{}, roots
return nil
default:
k := fmt.Sprintf("%s", strings.Join(sliceFormat(roots, e.Formatters), "."))
w[k] = f.Interface()
if e.ExtraFields.DeepJSON && (f.Kind() == reflect.String) {
if err := e.fDumpJSON(w, f.Interface().(string), roots, k); err != nil {
return err
}
} else {
w[k] = f.Interface()
}

}
return nil
}

func (e *Encoder) fDumpJSON(w map[string]interface{}, i string, roots []string, k string) error {
var value interface{}
bodyJSONArray := []interface{}{}
// Try to parse as a json array
if err := json.Unmarshal([]byte(i), &bodyJSONArray); err != nil {
//Try to parse as a map
bodyJSONMap := map[string]interface{}{}
if err2 := json.Unmarshal([]byte(i), &bodyJSONMap); err2 == nil {
value = bodyJSONMap
} else {
value = i
}
} else {
value = bodyJSONArray
}

if value == i {
w[k] = i
return nil
}
if err := e.fdumpInterface(w, value, roots); err != nil {
return err
}
return nil
}

func (e *Encoder) fDumpArray(w map[string]interface{}, i interface{}, roots []string) error {
f := valueFromInterface(i)
if _, ok := f.Interface().([]byte); ok {
if err := e.fdumpInterface(w, string(f.Interface().([]byte)), roots); err != nil {
return err
}
return nil
}

if e.ExtraFields.Type {
nodeType := append(roots, "__Type__")
nodeTypeFormatted := strings.Join(sliceFormat(nodeType, e.Formatters), ".")
w[nodeTypeFormatted] = "Array"
}

v := reflect.ValueOf(i)

if e.ExtraFields.Len {
Expand Down
47 changes: 45 additions & 2 deletions test/dump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ package test

import (
"bytes"
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"

"encoding/json"

"github.com/fsamin/go-dump"
)

Expand Down Expand Up @@ -424,3 +423,47 @@ T.B: foo bar
T.__Len__: 2
`, res)
}

func TestDumpJSONInString(t *testing.T) {
type T struct {
A int
B string
}
value := T{
A: 0,
B: "{ \"toctoc\": \"Qui est la\"}",
}

e := dump.NewDefaultEncoder(new(bytes.Buffer))
e.Formatters = []dump.KeyFormatterFunc{dump.WithDefaultLowerCaseFormatter()}
e.ExtraFields.DetailedMap = false
e.ExtraFields.DetailedStruct = false
e.ExtraFields.DeepJSON = true
e.ExtraFields.Len = false
e.ExtraFields.Type = false
m, err := e.ToStringMap(value)
assert.NoError(t, err)
assert.Equal(t, "Qui est la", m["t.b.toctoc"])
}

func TestNoDumpJSONInString(t *testing.T) {
type T struct {
A int
B string
}
value := T{
A: 0,
B: "{ \"toctoc\": \"Qui est la\"}",
}

e := dump.NewDefaultEncoder(new(bytes.Buffer))
e.Formatters = []dump.KeyFormatterFunc{dump.WithDefaultLowerCaseFormatter()}
e.ExtraFields.DetailedMap = false
e.ExtraFields.DetailedStruct = false
e.ExtraFields.DeepJSON = false
e.ExtraFields.Len = false
e.ExtraFields.Type = false
m, err := e.ToStringMap(value)
assert.NoError(t, err)
assert.Equal(t, "{ \"toctoc\": \"Qui est la\"}", m["t.b"])
}

0 comments on commit 7ae1b0f

Please sign in to comment.