diff --git a/util/gutil/gutil_dump.go b/util/gutil/gutil_dump.go index e8f5f2185..d0bfacbe9 100644 --- a/util/gutil/gutil_dump.go +++ b/util/gutil/gutil_dump.go @@ -15,6 +15,16 @@ import ( "reflect" ) +// apiString is used for type assert api for String(). +type apiString interface { + String() string +} + +// apiMapStrAny is the interface support for converting struct parameter to map. +type apiMapStrAny interface { + MapStrAny() map[string]interface{} +} + // Dump prints variables to stdout with more manually readable. func Dump(i ...interface{}) { s := Export(i...) @@ -27,11 +37,16 @@ func Dump(i ...interface{}) { func Export(i ...interface{}) string { buffer := bytes.NewBuffer(nil) for _, v := range i { - if b, ok := v.([]byte); ok { - buffer.Write(b) - } else { - rv := reflect.ValueOf(v) - kind := rv.Kind() + switch r := v.(type) { + case []byte: + buffer.Write(r) + case string: + buffer.WriteString(r) + default: + var ( + rv = reflect.ValueOf(v) + kind = rv.Kind() + ) if kind == reflect.Ptr { rv = rv.Elem() kind = rv.Kind() @@ -39,8 +54,14 @@ func Export(i ...interface{}) string { switch kind { case reflect.Slice, reflect.Array: v = gconv.Interfaces(v) - case reflect.Map, reflect.Struct: + case reflect.Map: v = gconv.Map(v) + case reflect.Struct: + if r, ok := v.(apiMapStrAny); ok { + v = r.MapStrAny() + } else if r, ok := v.(apiString); ok { + v = r.String() + } } encoder := json.NewEncoder(buffer) encoder.SetEscapeHTML(false)