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
|
// be spewed to strings and sorted by those strings. This is only
|
||||||
// considered if SortKeys is true.
|
// considered if SortKeys is true.
|
||||||
SpewKeys bool
|
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.
|
// Config is the active configuration of the top-level functions.
|
||||||
|
@ -301,6 +305,7 @@ func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{})
|
||||||
// DisablePointerMethods: false
|
// DisablePointerMethods: false
|
||||||
// ContinueOnMethod: false
|
// ContinueOnMethod: false
|
||||||
// SortKeys: false
|
// SortKeys: false
|
||||||
|
// OmitEmpty: false
|
||||||
func NewDefaultConfig() *ConfigState {
|
func NewDefaultConfig() *ConfigState {
|
||||||
return &ConfigState{Indent: " "}
|
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()
|
vt := v.Type()
|
||||||
numFields := v.NumField()
|
numFields := v.NumField()
|
||||||
for i := 0; i < numFields; i++ {
|
for i := 0; i < numFields; i++ {
|
||||||
|
vf := v.Field(i)
|
||||||
|
if d.cs.OmitEmpty && isZero(vf) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
d.indent()
|
d.indent()
|
||||||
vtf := vt.Field(i)
|
vtf := vt.Field(i)
|
||||||
d.w.Write([]byte(vtf.Name))
|
d.w.Write([]byte(vtf.Name))
|
||||||
d.w.Write(colonSpaceBytes)
|
d.w.Write(colonSpaceBytes)
|
||||||
d.ignoreNextIndent = true
|
d.ignoreNextIndent = true
|
||||||
d.dump(d.unpackValue(v.Field(i)))
|
d.dump(d.unpackValue(vf))
|
||||||
if i < (numFields - 1) {
|
if i < (numFields - 1) {
|
||||||
d.w.Write(commaNewlineBytes)
|
d.w.Write(commaNewlineBytes)
|
||||||
} else {
|
} else {
|
||||||
|
@ -507,3 +511,26 @@ get the formatted result as a string.
|
||||||
func Dump(a ...interface{}) {
|
func Dump(a ...interface{}) {
|
||||||
fdump(&Config, os.Stdout, a...)
|
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