Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: type specific hooks #64

Open
dionysius opened this issue Jun 23, 2024 · 0 comments
Open

Proposal: type specific hooks #64

dionysius opened this issue Jun 23, 2024 · 0 comments

Comments

@dionysius
Copy link

dionysius commented Jun 23, 2024

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 Equal method
  • 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 Equal method 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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant