Skip to content

Commit b53a548

Browse files
authored
fix: add map with pointer value support (#76)
1 parent b723d66 commit b53a548

3 files changed

Lines changed: 42 additions & 0 deletions

File tree

diff_pointer.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,18 @@ func (d *Differ) diffPtr(path []string, a, b reflect.Value, parent interface{})
1717
if !b.IsNil() {
1818
return d.diff(path, reflect.ValueOf(nil), reflect.Indirect(b), parent)
1919
}
20+
21+
d.cl.Add(CREATE, path, nil, exportInterface(b), parent)
22+
return nil
2023
}
2124

2225
if b.Kind() == reflect.Invalid {
2326
if !a.IsNil() {
2427
return d.diff(path, reflect.Indirect(a), reflect.ValueOf(nil), parent)
2528
}
29+
30+
d.cl.Add(DELETE, path, exportInterface(a), nil, parent)
31+
return nil
2632
}
2733

2834
return ErrTypeMismatch

patch.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,14 @@ func (d *Differ) renderChangeTarget(c *ChangeValue) {
188188

189189
//walking a path means dealing with real elements
190190
case reflect.Interface, reflect.Ptr:
191+
if c.target.IsNil() {
192+
n := reflect.New(c.target.Type().Elem())
193+
c.target.Set(n)
194+
c.target = &n
195+
d.renderChangeTarget(c)
196+
return
197+
}
198+
191199
el := c.target.Elem()
192200
c.target = &el
193201
c.ClearFlag(FlagInvalidTarget)

patch_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,34 @@ func TestPatch(t *testing.T) {
304304
assert.False(t, patchLog.HasErrors())
305305
})
306306

307+
t.Run("map-to-pointer", func(t *testing.T) {
308+
t1 := make(map[string]*tmstruct)
309+
t2 := map[string]*tmstruct{"after": {Foo: "val"}}
310+
311+
changelog, err := diff.Diff(t1, t2)
312+
assert.NoError(t, err)
313+
314+
patchLog := diff.Patch(changelog, &t1)
315+
assert.False(t, patchLog.HasErrors())
316+
317+
assert.True(t, len(t2) == len(t1))
318+
assert.Equal(t, t1["after"], &tmstruct{Foo: "val"})
319+
})
320+
321+
t.Run("map-to-nil-pointer", func(t *testing.T) {
322+
t1 := make(map[string]*tmstruct)
323+
t2 := map[string]*tmstruct{"after": nil}
324+
325+
changelog, err := diff.Diff(t1, t2)
326+
assert.NoError(t, err)
327+
328+
patchLog := diff.Patch(changelog, &t1)
329+
assert.False(t, patchLog.HasErrors())
330+
331+
assert.Equal(t, len(t2), len(t1))
332+
assert.Nil(t, t1["after"])
333+
})
334+
307335
t.Run("pointer-with-converted-type", func(t *testing.T) {
308336
type tps struct {
309337
S *int

0 commit comments

Comments
 (0)