Implementing OmitEmpty flag to skip zero-value fields.
This commit is contained in:
parent
8991bc29aa
commit
e7459a5405
|
@ -98,6 +98,10 @@ type ConfigState struct {
|
|||
// be spewed to strings and sorted by those strings. This is only
|
||||
// considered if SortKeys is true.
|
||||
SpewKeys bool
|
||||
|
||||
// OmitEmpty specifies that empty struct fields should be omitted.
|
||||
// Empty fields are any that have the zero value for their type.
|
||||
OmitEmpty bool
|
||||
}
|
||||
|
||||
// Config is the active configuration of the top-level functions.
|
||||
|
@ -301,6 +305,7 @@ func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{})
|
|||
// DisablePointerMethods: false
|
||||
// ContinueOnMethod: false
|
||||
// SortKeys: false
|
||||
// OmitEmpty: false
|
||||
func NewDefaultConfig() *ConfigState {
|
||||
return &ConfigState{Indent: " "}
|
||||
}
|
||||
|
|
29
spew/dump.go
29
spew/dump.go
|
@ -413,12 +413,16 @@ func (d *dumpState) dump(v reflect.Value) {
|
|||
vt := v.Type()
|
||||
numFields := v.NumField()
|
||||
for i := 0; i < numFields; i++ {
|
||||
vf := v.Field(i)
|
||||
if d.cs.OmitEmpty && isZero(vf) {
|
||||
continue
|
||||
}
|
||||
d.indent()
|
||||
vtf := vt.Field(i)
|
||||
d.w.Write([]byte(vtf.Name))
|
||||
d.w.Write(colonSpaceBytes)
|
||||
d.ignoreNextIndent = true
|
||||
d.dump(d.unpackValue(v.Field(i)))
|
||||
d.dump(d.unpackValue(vf))
|
||||
if i < (numFields - 1) {
|
||||
d.w.Write(commaNewlineBytes)
|
||||
} else {
|
||||
|
@ -507,3 +511,26 @@ get the formatted result as a string.
|
|||
func Dump(a ...interface{}) {
|
||||
fdump(&Config, os.Stdout, a...)
|
||||
}
|
||||
|
||||
// isZero is a helper function that checks whether a reflect.Value has the zero value for its type.
|
||||
func isZero(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||
return v.Len() == 0
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Interface, reflect.Ptr, reflect.Chan:
|
||||
return v.IsNil()
|
||||
case reflect.UnsafePointer:
|
||||
return v.Pointer() == 0
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
return v.Complex() == 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1040,3 +1040,46 @@ func TestDumpSortedKeys(t *testing.T) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDumpOmitEmpty(t *testing.T) {
|
||||
cfg := spew.ConfigState{OmitEmpty: true, DisablePointerAddresses: true}
|
||||
type s struct {
|
||||
S1 *s
|
||||
S2 *s
|
||||
Int int
|
||||
Int8 int8
|
||||
Int16 int16
|
||||
Int32 int32
|
||||
Int64 int64
|
||||
Uint uint32
|
||||
Uint8 uint8
|
||||
Uint16 uint16
|
||||
Uint32 uint32
|
||||
Uint64 uint64
|
||||
Uintptr uintptr
|
||||
Float32 float32
|
||||
Float64 float64
|
||||
Complex64 complex64
|
||||
Complex128 complex128
|
||||
UnsafePtr unsafe.Pointer
|
||||
Interface interface{}
|
||||
Bool bool
|
||||
Chan chan string
|
||||
String string
|
||||
Map map[string]int
|
||||
Slice []string
|
||||
Array [0]string
|
||||
}
|
||||
s1 := s{S1: &s{S2: &s{Int: 5}}}
|
||||
actual := cfg.Sdump(s1)
|
||||
expected := "(spew_test.s) {\n" +
|
||||
"S1: (*spew_test.s)({\n" +
|
||||
"S2: (*spew_test.s)({\n" +
|
||||
"Int: (int) 5,\n" +
|
||||
"}),\n" +
|
||||
"}),\n" +
|
||||
"}\n"
|
||||
if actual != expected {
|
||||
t.Errorf("Omit empty fields incorrect:\n %v %v", actual, expected)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue