Proposal: type specific hooks
I understand that it doesn't make sense to go in and try to support all possible core-ish types. E.g. like json.RawMessage as in #62.
Requesting an Equal method for the parent type may not be the best way to solve the culprit, a few caveats:
- If that parent type was the one to be compared, there's no need anymore to use deep, one could just use the
Equalmethod - If the type is used in hundreds of different parent types, there's a lot of Equal methods to write (a generator could be used/created)
- The type in question as well the parent type(s) may not be in a package you control, so providing an
Equalmethod is actually impossible
What I've seen in different other utilities is to offer a Hook for a type, which could be what is just missing. deep doesn't need to understand the type except to provide the framework for these hooks and this also allows to prototype a compare functions also for foreign types.
Examples:
deep already uses the package reflect, so there's no additional package needed.
Idea very rough from mind and may be incorrect. Good enough to show the idea:
import "reflect"
// signature of an equal func
type EqualFunc func(a, b reflect.Value) (bool, error)
// holds all the provided custom equal funcs
var customEqualFuncs map[reflect.Type]EqualFunc
// add a custom equal func
func SetEqualFunc(t reflect.Type, f EqualFunc ) {
customEqualFuncs[t] = f
}
// during equal() check whether a custom equal method exists
func equal(a, b interface{}) ... {
...
// ^ has no Equal method, check if a custom equal func exists
t := reflect.TypeOf(a)
if f, exists := customEqualFuncs[t]; exists {
isequal, err := f(reflect.ValueOf(a),reflect.ValueOf(b))
...
return ...
}
}
Would be used like:
deep.SetEqualFunc(reflect.TypeOf(json.RawMessage{}), func ... {
....
return isequal, iserr
}
Missing above: diff return, which would need to be incorporated in the idea as well
Options to explore for EqualFunc:
type EqualFunc func(a, b interface) (bool, error)and use actual values instead of reflect.Value- using generics
Is such a hook a fitting candidate for deep in your opinion?
Seems like a good idea because it wouldn't change the API but it would let users add functionality for bespoke data structures and comparisons.