From be3229dfd12a79f742330d6a5d1e760fbf230807 Mon Sep 17 00:00:00 2001 From: Tom Bevan Date: Thu, 16 Dec 2021 12:09:57 +0000 Subject: [PATCH] fix pointers when convert types is enabled --- change_value.go | 25 ++++++++++++++++++++----- patch_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/change_value.go b/change_value.go index 156b6aa..529554b 100644 --- a/change_value.go +++ b/change_value.go @@ -118,12 +118,27 @@ func (c *ChangeValue) Set(value reflect.Value, convertCompatibleTypes bool) { } if convertCompatibleTypes { - if !value.Type().ConvertibleTo(c.target.Type()) { - c.AddError(fmt.Errorf("Value of type %s is not convertible to %s", value.Type().String(), c.target.Type().String())) - c.SetFlag(FlagFailed) - return + if c.target.Kind() == reflect.Ptr && value.Kind() != reflect.Ptr { + if !value.Type().ConvertibleTo(c.target.Elem().Type()) { + c.AddError(fmt.Errorf("Value of type %s is not convertible to %s", value.Type().String(), c.target.Type().String())) + c.SetFlag(FlagFailed) + return + } + + fmt.Println(c.target.Elem().Type()) + + tv := reflect.New(c.target.Elem().Type()) + tv.Elem().Set(value.Convert(c.target.Elem().Type())) + c.target.Set(tv) + } else { + if !value.Type().ConvertibleTo(c.target.Type()) { + c.AddError(fmt.Errorf("Value of type %s is not convertible to %s", value.Type().String(), c.target.Type().String())) + c.SetFlag(FlagFailed) + return + } + + c.target.Set(value.Convert(c.target.Type())) } - c.target.Set(value.Convert(c.target.Type())) } else { if value.IsValid() { if c.target.Kind() == reflect.Ptr && value.Kind() != reflect.Ptr { diff --git a/patch_test.go b/patch_test.go index 63fd69a..bb69e7a 100644 --- a/patch_test.go +++ b/patch_test.go @@ -1,6 +1,7 @@ package diff_test import ( + "encoding/json" "testing" "time" @@ -303,3 +304,32 @@ func TestPatchPointer(t *testing.T) { patchLog := diff.Patch(changelog, &t1) assert.False(t, patchLog.HasErrors()) } + +func TestPatchPointerConvertTypes(t *testing.T) { + type tps struct { + S *int + } + + val1 := 1 + val2 := 2 + + t1 := tps{S: &val1} + t2 := tps{S: &val2} + + changelog, err := diff.Diff(t1, t2) + assert.NoError(t, err) + + js, err := json.Marshal(changelog) + assert.NoError(t, err) + + assert.NoError(t, json.Unmarshal(js, &changelog)) + + d, err := diff.NewDiffer(diff.ConvertCompatibleTypes()) + assert.NoError(t, err) + + assert.Equal(t, 1, *t1.S) + + patchLog := d.Patch(changelog, &t1) + assert.False(t, patchLog.HasErrors()) + assert.Equal(t, 2, *t1.S) +}