Skip to content

Commit

Permalink
Merge pull request #7 from m-mizutani/fix/copy-pointer
Browse files Browse the repository at this point in the history
Enhance and simplify clone logic
  • Loading branch information
m-mizutani authored Sep 2, 2023
2 parents 6bc7042 + 2e121ad commit 7f9339d
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 37 deletions.
51 changes: 27 additions & 24 deletions clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,35 @@ func (x *masq) clone(fieldName string, value reflect.Value, tag string) reflect.
return value
}

adjustValue := func(ret reflect.Value) reflect.Value {
switch value.Kind() {
case reflect.Ptr, reflect.Map, reflect.Slice, reflect.Array:
return ret
default:
return ret.Elem()
}
}

src := value
if value.Kind() == reflect.Ptr {
if value.IsNil() {
return reflect.New(value.Type()).Elem()
}
src = value.Elem()
}

var dst reflect.Value
if x.filters.ShouldRedact(fieldName, src.Interface(), tag) {
dst = reflect.New(src.Type())
dst := reflect.New(src.Type())
switch src.Kind() {
case reflect.String:
dst.Elem().SetString(x.RedactMessage)
case reflect.Array, reflect.Slice, reflect.Map:
dst = dst.Elem()
}
return adjustValue(dst)

if !dst.CanInterface() {
return dst
}
return dst.Elem()
}

switch src.Kind() {
case reflect.String:
dst = reflect.New(src.Type())
dst := reflect.New(src.Type())
filtered := x.filters.ReplaceString(value.String())
dst.Elem().SetString(filtered)
return dst.Elem()

case reflect.Struct:
dst = reflect.New(src.Type())
dst := reflect.New(src.Type())
t := src.Type()

for i := 0; i < t.NumField(); i++ {
Expand All @@ -63,38 +55,49 @@ func (x *masq) clone(fieldName string, value reflect.Value, tag string) reflect.
dstValue = reflect.NewAt(dstValue.Type(), unsafe.Pointer(dstValue.UnsafeAddr())).Elem()
}

dstValue.Set(x.clone(f.Name, srcValue, f.Tag.Get("masq")))
tagValue := f.Tag.Get("masq")
copied := x.clone(f.Name, srcValue, tagValue)
dstValue.Set(copied)
}
return dst.Elem()

case reflect.Map:
dst = reflect.MakeMap(src.Type())
dst := reflect.MakeMap(src.Type())
keys := src.MapKeys()
for i := 0; i < src.Len(); i++ {
mValue := src.MapIndex(keys[i])
dst.SetMapIndex(keys[i], x.clone(keys[i].String(), mValue, ""))
}
return dst

case reflect.Slice:
dst = reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
dst := reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
for i := 0; i < src.Len(); i++ {
dst.Index(i).Set(x.clone(fieldName, src.Index(i), ""))
}
return dst

case reflect.Array:
if src.Len() == 0 {
return src // can not access to src.Index(0)
}

arrType := reflect.ArrayOf(src.Len(), src.Index(0).Type())
dst = reflect.New(arrType).Elem()
dst := reflect.New(arrType).Elem()
for i := 0; i < src.Len(); i++ {
dst.Index(i).Set(x.clone(fieldName, src.Index(i), ""))
}
return dst

case reflect.Ptr:
dst := reflect.New(src.Elem().Type())
copied := x.clone(fieldName, src.Elem(), tag)
dst.Elem().Set(copied)
return dst

default:
dst = reflect.New(src.Type())
dst := reflect.New(src.Type())
dst.Elem().Set(src)
return dst.Elem()
}

return adjustValue(dst)
}
75 changes: 68 additions & 7 deletions clone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,18 @@ func TestClone(t *testing.T) {
Chan chan int
Bool bool
Bytes []byte
Array [2]string
Interface interface{}
Child *child
}
data := &myStruct{
Func: time.Now,
Chan: make(chan int),
Bool: true,
Bytes: []byte("timeless"),
Child: nil,
Func: time.Now,
Chan: make(chan int),
Bool: true,
Bytes: []byte("timeless"),
Array: [2]string{"aa", "bb"},
Interface: &struct{}{},
Child: nil,
}
copied := gt.MustCast[*myStruct](t, c.Redact(data)).NotNil()

Expand All @@ -177,8 +180,9 @@ func TestClone(t *testing.T) {
gt.V(t, copied.Chan).Equal(data.Chan)
gt.V(t, copied.Bool).Equal(data.Bool)
gt.V(t, copied.Bytes).Equal(data.Bytes)
gt.V(t, copied.Array).Equal(data.Array)
gt.V(t, copied.Interface).Equal(data.Interface)
})

})

t.Run("filter various type", func(t *testing.T) {
Expand Down Expand Up @@ -222,6 +226,63 @@ func TestClone(t *testing.T) {
gt.Value(t, copied.StrsPtr).Nil()
gt.Value(t, copied.Interface).Nil()
gt.Value(t, copied.Child.Data).Equal("")
gt.Value(t, copied.ChildPtr.Data).Equal("")
gt.Value(t, copied.ChildPtr).Nil()
})
}

func TestMapData(t *testing.T) {
c := masq.NewMasq(masq.WithString("blue"))

type testData struct {
ID int
Name string
Label string
}

data := map[string]*testData{
"xyz": {
Name: "blue",
Label: "five",
},
}
copied := gt.MustCast[map[string]*testData](t, c.Redact(data)).NotNil()

gt.V(t, copied["xyz"].Name).Equal(masq.DefaultRedactMessage)
gt.V(t, copied["xyz"].Label).Equal("five")

}

func TestCloneUnexportedPointer(t *testing.T) {
c := masq.NewMasq(masq.WithString("blue"))
type child struct {
Name string
}
type myStruct struct {
c *child
}
data := &myStruct{
c: &child{
Name: "orange",
},
}
copied := gt.MustCast[*myStruct](t, c.Redact(data)).NotNil()
gt.V(t, copied.c.Name).Equal("orange")
}

func TestDoublePointer(t *testing.T) {
c := masq.NewMasq(masq.WithString("blue"))
type child struct {
Name string
}
type myStruct struct {
c **child
}
childData := &child{
Name: "orange",
}
data := &myStruct{
c: &childData,
}
copied := gt.MustCast[*myStruct](t, c.Redact(data)).NotNil()
gt.V(t, (*copied.c).Name).Equal("orange")
}
5 changes: 1 addition & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ module github.com/m-mizutani/masq

go 1.21

require (
github.com/m-mizutani/gt v0.0.0-20221229045033-48cc67569435
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
)
require github.com/m-mizutani/gt v0.0.0-20221229045033-48cc67569435

require github.com/google/go-cmp v0.5.9 // indirect
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,3 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/m-mizutani/gt v0.0.0-20221229045033-48cc67569435 h1:4EZ4iNhfccquGCmAAGer708a/mrKKVRWGrErPS2c850=
github.com/m-mizutani/gt v0.0.0-20221229045033-48cc67569435/go.mod h1:0MPYSfGBLmYjTduzADVmIqD58ELQ5IfBFiK/f0FmB3k=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=

0 comments on commit 7f9339d

Please sign in to comment.