Skip to content

Commit

Permalink
feat: if err occur, dst will recover to init
Browse files Browse the repository at this point in the history
  • Loading branch information
XiXiangFiles committed Nov 19, 2023
1 parent 70b1d4e commit 71d7442
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 1 deletion.
9 changes: 9 additions & 0 deletions copier.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,15 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
return ErrInvalidCopyFrom
}

cacheToValue := indirect(reflect.New(to.Type()))
cacheToValue.Set(to)
defer func() {
// if err occur, toValue needs to recover to init state.
if err != nil {
to.Set(cacheToValue)
}
}()

fromType, isPtrFrom := indirectType(from.Type())
toType, _ := indirectType(to.Type())

Expand Down
68 changes: 67 additions & 1 deletion copier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1665,7 +1665,6 @@ func TestDeepCopyAnonymousFieldTime(t *testing.T) {
}

func TestSqlNullFiled(t *testing.T) {

type sqlStruct struct {
MkId sql.NullInt64
MkExpiryDateType sql.NullInt32
Expand Down Expand Up @@ -1762,3 +1761,70 @@ func TestNestedNilPointerStruct(t *testing.T) {
t.Errorf("to (%v) value should equal from (%v) value", to.Title, from.Title)
}
}

func TestOccurErr(t *testing.T) {
t.Run("CopyWithOption err occur", func(t *testing.T) {
type srcTags struct {
Field string
Index int
}
type destTags struct {
Field string
Index string
}

dst := &destTags{
Field: "init",
Index: "0",
}
src := &srcTags{
Field: "copied",
Index: 1,
}
err := copier.CopyWithOption(dst, src, copier.Option{
Converters: []copier.TypeConverter{
{
SrcType: 1,
DstType: "",
Fn: func(src interface{}) (dst interface{}, err error) {
return nil, fmt.Errorf("return err")
},
},
},
})
if err == nil {
t.Errorf("should return err")
}
if dst.Field != "init" || dst.Index != "0" {
t.Error("when err occur, the dst should be init")
}

})
t.Run("copy err occur", func(t *testing.T) {
type srcTags struct {
field string
Field2 string
}

type destTags struct {
Field string `copier:"field"`
Field2 string `copier:"Field2"`
}

dst := &destTags{
Field: "init",
Field2: "init2",
}
src := &srcTags{
field: "Field1->Field1",
Field2: "Field2->Field2",
}
err := copier.Copy(dst, src)
if err == nil {
t.Errorf("should return err")
}
if dst.Field != "init" || dst.Field2 != "init2" {
t.Error("when err occur, the dst should be init")
}
})
}

0 comments on commit 71d7442

Please sign in to comment.