Skip to content

Commit 5499b50

Browse files
committed
Tag omitzero respects IsZero()
1 parent 4b439bf commit 5499b50

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

encode.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,34 @@ func getOptions(tag reflect.StructTag) tagOptions {
663663
return opts
664664
}
665665

666+
func callIsZero(rv reflect.Value) (bool, bool) {
667+
if !rv.IsValid() {
668+
return false, false
669+
}
670+
671+
isZeroMethod := rv.MethodByName("IsZero")
672+
if !isZeroMethod.IsValid() {
673+
return false, false
674+
}
675+
676+
methodType := isZeroMethod.Type()
677+
if methodType.NumIn() != 0 || methodType.NumOut() != 1 || methodType.Out(0) != reflect.TypeOf(true) {
678+
return false, false
679+
}
680+
681+
returnValues := isZeroMethod.Call(nil)
682+
if len(returnValues) == 1 && returnValues[0].Kind() == reflect.Bool {
683+
return returnValues[0].Bool(), true
684+
}
685+
686+
return false, false
687+
}
688+
666689
func isZero(rv reflect.Value) bool {
690+
if zero, ok := callIsZero(rv); ok {
691+
return zero
692+
}
693+
667694
switch rv.Kind() {
668695
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
669696
return rv.Int() == 0

encode_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,24 +274,34 @@ slice = ["XXX"]
274274
})
275275
}
276276

277+
// a test type that is zero when its value is 42
278+
type int42 int
279+
280+
func (i int42) IsZero() bool {
281+
return i == 42
282+
}
283+
277284
func TestEncodeOmitZero(t *testing.T) {
278285
type simple struct {
279286
Number int `toml:"number,omitzero"`
280287
Real float64 `toml:"real,omitzero"`
281288
Unsigned uint `toml:"unsigned,omitzero"`
289+
Int42 int42 `toml:"int42,omitzero"`
282290
}
283291

284-
value := simple{0, 0.0, uint(0)}
292+
value := simple{0, 0.0, uint(0), int42(42)}
285293
expected := ""
286294

287295
encodeExpected(t, "simple with omitzero, all zero", value, expected, nil)
288296

289297
value.Number = 10
290298
value.Real = 20
291299
value.Unsigned = 5
300+
value.Int42 = int42(13) // this is zero for our custom type
292301
expected = `number = 10
293302
real = 20.0
294303
unsigned = 5
304+
int42 = 13
295305
`
296306
encodeExpected(t, "simple with omitzero, non-zero", value, expected, nil)
297307
}

0 commit comments

Comments
 (0)