From 7b41f8cfb4fce97fcdd28e0fe6c3886e0da6295d Mon Sep 17 00:00:00 2001 From: ag9920 Date: Tue, 8 Mar 2022 17:05:18 +0800 Subject: [PATCH] fix: prevent reinitialize error at getFlags --- copier.go | 12 ++++-------- copier_tags_test.go | 24 ++++++++++++++++++++++++ copier_test.go | 20 +++++++++----------- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/copier.go b/copier.go index 5fba6b8..05a5534 100644 --- a/copier.go +++ b/copier.go @@ -232,7 +232,8 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) } // Get tag options - flgs, err := getFlags(dest, source, toType, fromType) + var flgs flags + flgs, err = getFlags(dest, source, toType, fromType) if err != nil { return err } @@ -247,7 +248,7 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) name := field.Name // Get bit flags for field - fieldFlags, _ := flgs.BitFlags[name] + fieldFlags := flgs.BitFlags[name] // Check if we should ignore copying if (fieldFlags & tagIgnore) != 0 { @@ -537,21 +538,17 @@ func lookupAndCopyWithConverter(to, from reflect.Value, converters map[converter if cnv, ok := converters[pair]; ok { result, err := cnv.Fn(from.Interface()) - if err != nil { return false, err } - if result != nil { to.Set(reflect.ValueOf(result)) } else { // in case we've got a nil value to copy to.Set(reflect.Zero(to.Type())) } - return true, nil } - return false, nil } @@ -640,7 +637,7 @@ func checkBitFlags(flagsList map[string]uint8) (err error) { err = fmt.Errorf("field %s has must tag but was not copied", name) return case flgs&(tagMust) != 0: - panic(fmt.Sprintf("Field %s has must tag but was not copied", name)) + panic(fmt.Sprintf("field %s has must tag but was not copied", name)) } } } @@ -682,7 +679,6 @@ func getFieldName(fieldName string, flgs flags) (srcFieldName string, destFieldN } func driverValuer(v reflect.Value) (i driver.Valuer, ok bool) { - if !v.CanAddr() { i, ok = v.Interface().(driver.Valuer) return diff --git a/copier_tags_test.go b/copier_tags_test.go index c8fe704..2c65ee8 100644 --- a/copier_tags_test.go +++ b/copier_tags_test.go @@ -49,6 +49,30 @@ func TestCopyTagMust(t *testing.T) { copier.Copy(employee, user) } +func TestCopyTagMustNoPanic(t *testing.T) { + type Student struct { + Name string + } + type Person struct { + Name string + Grade string `copier:"must,nopanic"` + } + + student := &Student{ + Name: "jing1", + } + person := &Person{} + defer func() { + if r := recover(); r != nil { + t.Error("Expected no panic.") + } + }() + err := copier.Copy(person, student) + if err == nil { + t.Errorf("Expected err for not copy, got nil") + } +} + func TestCopyTagFieldName(t *testing.T) { t.Run("another name field copy", func(t *testing.T) { type SrcTags struct { diff --git a/copier_test.go b/copier_test.go index f6d68a4..2c0fdf5 100644 --- a/copier_test.go +++ b/copier_test.go @@ -1203,7 +1203,7 @@ func TestCopyMapOfInt(t *testing.T) { func TestCopyMapOfSliceValue(t *testing.T) { // case1: map's value is a simple slice key, value := 2, 3 - src := map[int][]int{key: []int{value} } + src := map[int][]int{key: []int{value}} dst1 := map[int][]int{} var dst2 map[int][]int err := copier.Copy(&dst1, src) @@ -1240,10 +1240,10 @@ func TestCopyMapOfSliceValue(t *testing.T) { // case2: map's value is a slice whose element is map key1, key2 := 2, 3 value = 4 - s := map[int][]map[int]int{key1: []map[int]int{ {key2: value} } } - d1 := map[int][]map[int]int{key1: []map[int]int{ {key1: key2 } } } - d2 := map[int][]map[int]int{key1: []map[int]int{ } } - d3 := map[int][]map[int]int{key1: nil } + s := map[int][]map[int]int{key1: []map[int]int{{key2: value}}} + d1 := map[int][]map[int]int{key1: []map[int]int{{key1: key2}}} + d2 := map[int][]map[int]int{key1: []map[int]int{}} + d3 := map[int][]map[int]int{key1: nil} d4 := map[int][]map[int]int{} d5 := map[int][]map[int]int(nil) ms := []map[int][]map[int]int{d1, d2, d3, d4, d5} @@ -1267,7 +1267,7 @@ func TestCopyMapOfSliceValue(t *testing.T) { for k, v := range m { if k != key2 || v != value { t.Errorf("Map's slice value should be copied recursively") - } + } } } } @@ -1276,7 +1276,7 @@ func TestCopyMapOfSliceValue(t *testing.T) { func TestCopyMapOfPtrValue(t *testing.T) { intV := 3 intv := intV - src := map[int]*int{2: &intv } + src := map[int]*int{2: &intv} dst1 := map[int]*int{} var dst2 map[int]*int err := copier.Copy(&dst1, src) @@ -1295,7 +1295,7 @@ func TestCopyMapOfPtrValue(t *testing.T) { } v3, ok := dst2[k] - if !ok || v3 == nil ||*v3 != *v1 || *v3 != intV { + if !ok || v3 == nil || *v3 != *v1 || *v3 != intV { t.Errorf("Map should be copied") } } @@ -1520,7 +1520,6 @@ func TestDeepCopyTime(t *testing.T) { } } - func TestNestedPrivateData(t *testing.T) { type hasPrivate struct { data int @@ -1558,7 +1557,6 @@ func TestNestedPrivateData(t *testing.T) { } } - func TestDeepMapCopyTime(t *testing.T) { t1 := time.Now() t2 := t1.Add(time.Second) @@ -1611,7 +1609,7 @@ func TestDeepCopySimpleTime(t *testing.T) { } } -type TimeWrapper struct{ +type TimeWrapper struct { time.Time }