diff icon indicating copy to clipboard operation
diff copied to clipboard

Patching complex struct with map[customType]customSlice fails: value of type string is not assignable to type customMap

Open pikaro opened this issue 1 year ago • 0 comments

github.com/r3labs/diff/v3 v3.0.1

I just ran into a bug / unexpected behavior when trying to diff and patch a complex struct with custom types. Not sure if this is out of scope or already covered by the documentation, but it would be great to get some feedback either way.

package main

import (
	"fmt"

	"github.com/r3labs/diff/v3"
)

type (
	A string
	B string
)

type Inner struct {
	Value string
	Other string
}

type Key string

type (
	Slice []Inner
	Map   map[Key]Slice
)

type Outer struct {
	Map Map
}

func main() {
	s := Outer{
		Map: Map{
			"key": Slice{
				{
					Value: "value",
					Other: "other",
				},
			},
		},
	}

	s2 := Outer{
		Map: Map{
			"key": Slice{
				{
					Value: "value",
					Other: "other",
				},
				{
					Value: "valu2",
					Other: "othe2",
				},
			},
		},
	}

	differ, _ := diff.NewDiffer()

	delta, _ := differ.Diff(s, s2)
	fmt.Println(s)
	fmt.Println(s2)
	fmt.Println(delta)

	patchlog := differ.Patch(delta, &s)
	fmt.Printf("Have %d errors\n", patchlog.ErrorCount())

	for _, e := range patchlog {
		if e.Errors != nil {
			fmt.Println(e.Errors)
		}
	}

	fmt.Println(s)
}

This produces:

{map[key:[{value other}]]}
{map[key:[{value other} {valu2 othe2}]]}
[{create [Map key 1 Value] <nil> valu2 <nil>} {create [Map key 1 Other] <nil> othe2 <nil>}]
Have 2 errors
 reflect.Set: value of type string is not assignable to type main.Map (cause count 0)

 reflect.Set: value of type string is not assignable to type main.Map (cause count 0)

{map[key:[{value other}]]}

With diff.DisableStructValues(), I instead get:

{map[key:[{value other}]]}
{map[key:[{value other} {valu2 othe2}]]}
[{create [Map key 1] <nil> {valu2 othe2} <nil>}]
Have 1 errors
 reflect.Set: value of type main.Inner is not assignable to type main.Map (cause count 0)

{map[key:[{value other}]]}

If I remove all the non-struct custom types, it works as it should.

pikaro avatar Nov 09 '24 16:11 pikaro