github.phpd.cn/thought-machine/please@v12.2.0+incompatible/third_party/go/spew_omit_empty.patch (about) 1 diff --git a/config.go b/config.go 2 index 2e3d22f..2245869 100644 3 --- a/config.go 4 +++ b/config.go 5 @@ -76,6 +76,13 @@ type ConfigState struct { 6 // data structures in tests. 7 DisableCapacities bool 8 9 + // DisableTypes specifies whether to disable the printing of types. 10 + DisableTypes bool 11 + 12 + // DisableLengths specifies whether to disable the printing of lengths. 13 + // This also disables the printing of capacities. 14 + DisableLengths bool 15 + 16 // ContinueOnMethod specifies whether or not recursion should continue once 17 // a custom error or Stringer interface is invoked. The default, false, 18 // means it will print the results of invoking the custom error or Stringer 19 @@ -98,6 +105,10 @@ type ConfigState struct { 20 // be spewed to strings and sorted by those strings. This is only 21 // considered if SortKeys is true. 22 SpewKeys bool 23 + 24 + // OmitEmpty specifies that empty struct fields should be omitted. 25 + // Empty fields are any that have the zero value for their type. 26 + OmitEmpty bool 27 } 28 29 // Config is the active configuration of the top-level functions. 30 @@ -301,6 +312,7 @@ func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) 31 // DisablePointerMethods: false 32 // ContinueOnMethod: false 33 // SortKeys: false 34 +// OmitEmpty: false 35 func NewDefaultConfig() *ConfigState { 36 return &ConfigState{Indent: " "} 37 } 38 diff --git a/doc.go b/doc.go 39 index aacaac6..565d4d2 100644 40 --- a/doc.go 41 +++ b/doc.go 42 @@ -100,6 +100,13 @@ The following configuration options are available: 43 capacities for arrays, slices, maps and channels. This is useful when 44 diffing data structures in tests. 45 46 + * DisableTypes 47 + DisableTypes specifies whether to disable the printing of types. 48 + 49 + * DisableLengths 50 + DisableLengths specifies whether to disable the printing of lengths. 51 + This also disables the printing of capacities. 52 + 53 * ContinueOnMethod 54 Enables recursion into types after invoking error and Stringer interface 55 methods. Recursion after method invocation is disabled by default. 56 diff --git a/dump.go b/dump.go 57 index f78d89f..5aaa806 100644 58 --- a/dump.go 59 +++ b/dump.go 60 @@ -123,10 +123,12 @@ func (d *dumpState) dumpPtr(v reflect.Value) { 61 } 62 63 // Display type information. 64 - d.w.Write(openParenBytes) 65 - d.w.Write(bytes.Repeat(asteriskBytes, indirects)) 66 - d.w.Write([]byte(ve.Type().String())) 67 - d.w.Write(closeParenBytes) 68 + if !d.cs.DisableTypes { 69 + d.w.Write(openParenBytes) 70 + d.w.Write(bytes.Repeat(asteriskBytes, indirects)) 71 + d.w.Write([]byte(ve.Type().String())) 72 + d.w.Write(closeParenBytes) 73 + } 74 75 // Display pointer information. 76 if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 { 77 @@ -266,37 +268,41 @@ func (d *dumpState) dump(v reflect.Value) { 78 // Print type information unless already handled elsewhere. 79 if !d.ignoreNextType { 80 d.indent() 81 - d.w.Write(openParenBytes) 82 - d.w.Write([]byte(v.Type().String())) 83 - d.w.Write(closeParenBytes) 84 - d.w.Write(spaceBytes) 85 + if !d.cs.DisableTypes { 86 + d.w.Write(openParenBytes) 87 + d.w.Write([]byte(v.Type().String())) 88 + d.w.Write(closeParenBytes) 89 + d.w.Write(spaceBytes) 90 + } 91 } 92 d.ignoreNextType = false 93 94 // Display length and capacity if the built-in len and cap functions 95 // work with the value's kind and the len/cap itself is non-zero. 96 - valueLen, valueCap := 0, 0 97 - switch v.Kind() { 98 - case reflect.Array, reflect.Slice, reflect.Chan: 99 - valueLen, valueCap = v.Len(), v.Cap() 100 - case reflect.Map, reflect.String: 101 - valueLen = v.Len() 102 - } 103 - if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { 104 - d.w.Write(openParenBytes) 105 - if valueLen != 0 { 106 - d.w.Write(lenEqualsBytes) 107 - printInt(d.w, int64(valueLen), 10) 108 + if !d.cs.DisableLengths { 109 + valueLen, valueCap := 0, 0 110 + switch v.Kind() { 111 + case reflect.Array, reflect.Slice, reflect.Chan: 112 + valueLen, valueCap = v.Len(), v.Cap() 113 + case reflect.Map, reflect.String: 114 + valueLen = v.Len() 115 } 116 - if !d.cs.DisableCapacities && valueCap != 0 { 117 + if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { 118 + d.w.Write(openParenBytes) 119 if valueLen != 0 { 120 - d.w.Write(spaceBytes) 121 + d.w.Write(lenEqualsBytes) 122 + printInt(d.w, int64(valueLen), 10) 123 + } 124 + if !d.cs.DisableCapacities && valueCap != 0 { 125 + if valueLen != 0 { 126 + d.w.Write(spaceBytes) 127 + } 128 + d.w.Write(capEqualsBytes) 129 + printInt(d.w, int64(valueCap), 10) 130 } 131 - d.w.Write(capEqualsBytes) 132 - printInt(d.w, int64(valueCap), 10) 133 + d.w.Write(closeParenBytes) 134 + d.w.Write(spaceBytes) 135 } 136 - d.w.Write(closeParenBytes) 137 - d.w.Write(spaceBytes) 138 } 139 140 // Call Stringer/error interfaces if they exist and the handle methods flag 141 @@ -413,12 +419,16 @@ func (d *dumpState) dump(v reflect.Value) { 142 vt := v.Type() 143 numFields := v.NumField() 144 for i := 0; i < numFields; i++ { 145 + vf := v.Field(i) 146 + if d.cs.OmitEmpty && isZero(vf) { 147 + continue 148 + } 149 d.indent() 150 vtf := vt.Field(i) 151 d.w.Write([]byte(vtf.Name)) 152 d.w.Write(colonSpaceBytes) 153 d.ignoreNextIndent = true 154 - d.dump(d.unpackValue(v.Field(i))) 155 + d.dump(d.unpackValue(vf)) 156 if i < (numFields - 1) { 157 d.w.Write(commaNewlineBytes) 158 } else { 159 @@ -507,3 +517,26 @@ get the formatted result as a string. 160 func Dump(a ...interface{}) { 161 fdump(&Config, os.Stdout, a...) 162 } 163 + 164 +// isZero is a helper function that checks whether a reflect.Value has the zero value for its type. 165 +func isZero(v reflect.Value) bool { 166 + switch v.Kind() { 167 + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: 168 + return v.Len() == 0 169 + case reflect.Bool: 170 + return !v.Bool() 171 + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 172 + return v.Int() == 0 173 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 174 + return v.Uint() == 0 175 + case reflect.Float32, reflect.Float64: 176 + return v.Float() == 0 177 + case reflect.Interface, reflect.Ptr, reflect.Chan: 178 + return v.IsNil() 179 + case reflect.UnsafePointer: 180 + return v.Pointer() == 0 181 + case reflect.Complex64, reflect.Complex128: 182 + return v.Complex() == 0 183 + } 184 + return false 185 +}