Skip to content

Proposal: type specific hooks #64

Description

@dionysius

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?

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions