@@ -329,13 +329,37 @@ func isEmptyValue(v reflect.Value) bool {
329
329
return false
330
330
}
331
331
332
+ type isZeroer interface {
333
+ IsZero () bool
334
+ }
335
+
336
+ var isZeroerType = reflect .TypeFor [isZeroer ]()
337
+
332
338
func isZeroValue (v reflect.Value ) bool {
333
- if z , ok := v .Interface ().(interface {
334
- IsZero () bool
335
- }); ok {
336
- return z .IsZero ()
339
+ // Provide a function that uses a type's IsZero method.
340
+ var isZero func (reflect.Value ) bool
341
+
342
+ switch {
343
+ case v .Kind () == reflect .Interface && v .Type ().Implements (isZeroerType ):
344
+ isZero = func (va reflect.Value ) bool {
345
+ // Avoid panics calling IsZero on a nil interface or
346
+ // non-nil interface with nil pointer.
347
+ return va .IsNil () ||
348
+ (va .Elem ().Kind () == reflect .Pointer && va .Elem ().IsNil ()) ||
349
+ va .Interface ().(isZeroer ).IsZero ()
350
+ }
351
+ case v .Kind () == reflect .Pointer && v .Type ().Implements (isZeroerType ):
352
+ isZero = func (va reflect.Value ) bool {
353
+ // Avoid panics calling IsZero on nil pointer.
354
+ return va .IsNil () || va .Interface ().(isZeroer ).IsZero ()
355
+ }
356
+ case v .Type ().Implements (isZeroerType ):
357
+ isZero = func (va reflect.Value ) bool { return va .Interface ().(isZeroer ).IsZero () }
358
+ case reflect .PointerTo (v .Type ()).Implements (isZeroerType ):
359
+ isZero = func (va reflect.Value ) bool { return va .Addr ().Interface ().(isZeroer ).IsZero () }
337
360
}
338
- return v .IsZero ()
361
+
362
+ return (isZero == nil && v .IsZero () || (isZero != nil && isZero (v )))
339
363
}
340
364
341
365
func (e * encodeState ) reflectValue (v reflect.Value , opts encOpts ) {
0 commit comments