mirror of
https://github.com/DNSCrypt/dnscrypt-proxy.git
synced 2024-12-29 00:30:30 +01:00
55 lines
1.4 KiB
Go
55 lines
1.4 KiB
Go
// Package deepequal provides improved reflect.DeepEqual.
|
|
//
|
|
// Differences from reflect.DeepEqual:
|
|
//
|
|
// - If compared value implements `.Equal(valueOfSameType) bool` method then
|
|
// it will be called instead of comparing values as is.
|
|
// - If called `Equal` method will panics then whole DeepEqual will panics too.
|
|
//
|
|
// This means you can use this DeepEqual method to correctly compare types
|
|
// like time.Time or decimal.Decimal, without taking in account unimportant
|
|
// differences (like time zone or exponent).
|
|
package deepequal
|
|
|
|
import (
|
|
"reflect"
|
|
"unsafe"
|
|
)
|
|
|
|
// Disable check for unexported values.
|
|
func forceExported(v *reflect.Value) (undo func()) {
|
|
ref := (*value)(unsafe.Pointer(v))
|
|
flag := ref.flag
|
|
ref.flag &^= flagRO
|
|
return func() { ref.flag = flag }
|
|
}
|
|
|
|
func valueInterface(v reflect.Value) interface{} {
|
|
defer forceExported(&v)()
|
|
return v.Interface()
|
|
}
|
|
|
|
func call(v reflect.Value, in []reflect.Value) []reflect.Value {
|
|
defer forceExported(&v)()
|
|
for i := range in {
|
|
defer forceExported(&in[i])()
|
|
}
|
|
return v.Call(in)
|
|
}
|
|
|
|
var (
|
|
zeroValue reflect.Value
|
|
boolType = reflect.TypeOf(true)
|
|
)
|
|
|
|
func equalFunc(v reflect.Value) (equal reflect.Value, ok bool) {
|
|
equal = v.MethodByName("Equal")
|
|
if equal == zeroValue {
|
|
return zeroValue, false
|
|
}
|
|
typ := equal.Type()
|
|
ok = typ.NumIn() == 1 && typ.In(0) == v.Type() &&
|
|
typ.NumOut() == 1 && typ.Out(0) == boolType
|
|
return equal, ok
|
|
}
|