r3labs / diff

A library for diffing golang structures
Mozilla Public License 2.0
888 stars 80 forks source link

Patch against map doesn't work #60

Closed alextrs closed 3 years ago

alextrs commented 3 years ago

When I try to Patch map using code below

  testMap := map[string]interface{}{}
  testMap["firstName"] = "John"
  testMap["lastName"] = "Michael"
  testMap["createdBy"] = "TS"

  patchLog := diff.Patch(diff.Changelog{{
      Type: "update",
      Path: []string{"createdBy"},
      From: "TS",
      To:   "KS",
    }
  }, &testMap)
  Ω(patchLog[0].Errors).To(BeNil())

I get the following error

reflect.Set: value of type string is not assignable to type map[string]interface {}
purehyperbole commented 3 years ago

Hi @alextrs, sorry for the late response.

This should now be fixed on v2.13.2. Please let me know if it solves your issue!

alextrs commented 3 years ago

@purehyperbole thank you for fix. Got a lot closer, now getting -

    reflect: call of reflect.Value.NumField on interface Value
    /usr/local/Cellar/go@1.14/1.14.7.reinstall/libexec/src/reflect/value.go:208
    ...
    github.com/r3labs/diff/v2.(*Differ).deleteMapEntry(0xc0003a4240, 0xc0003a4300, 0xc0003a6260, 0xc0003a6280, 0xc0003a6240)
       /usr/local/Cellar/go@1.14/1.14.7/bin/pkg/mod/github.com/r3labs/diff/v2@v2.13.2/patch_map.go:80 +0xb1

If I change

func (d *Differ) deleteMapEntry(c *ChangeValue, m, k, v *reflect.Value) {
       ...
    if m != nil && m.CanSet() && v.IsValid() && v.Kind() != reflect.Int {
        for x := 0; x < v.NumField(); x++ {

with

func (d *Differ) deleteMapEntry(c *ChangeValue, m, k, v *reflect.Value) {
       ...
    if m != nil && m.CanSet() && v.IsValid() && v.Kind() == reflect.Struct {
        for x := 0; x < v.NumField(); x++ {

It fixes it too, not sure if it is right though.

purehyperbole commented 3 years ago

@alexflint Awesome! Yes that looks correct. Thanks!

I've pushed a new version with your change (v2.13.3).

alextrs commented 3 years ago

Works great, thank you.