1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-12 16:52:29 +08:00

feat: add CopyProperties for merge properties between structs

This commit is contained in:
dudaodong
2023-02-20 11:48:30 +08:00
parent 36fb3abe9e
commit 46de539e22
2 changed files with 94 additions and 0 deletions

View File

@@ -9,6 +9,7 @@ import (
"encoding/binary"
"encoding/gob"
"encoding/json"
"errors"
"fmt"
"math"
"reflect"
@@ -340,3 +341,46 @@ func DeepClone[T any](src T) T {
return result.Interface().(T)
}
// CopyProperties copies each field from the source into the destination. It recursively copies struct pointers and interfaces that contain struct pointers.
// Play: todo
func CopyProperties(dst, src interface{}) (err error) {
defer func() {
if e := recover(); e != nil {
err = errors.New(fmt.Sprintf("%v", e))
}
}()
dstType, dstValue := reflect.TypeOf(dst), reflect.ValueOf(dst)
srcType, srcValue := reflect.TypeOf(src), reflect.ValueOf(src)
if dstType.Kind() != reflect.Ptr || dstType.Elem().Kind() != reflect.Struct {
return errors.New("CopyProperties: param dst should be struct pointer")
}
if srcType.Kind() == reflect.Ptr {
srcType, srcValue = srcType.Elem(), srcValue.Elem()
}
if srcType.Kind() != reflect.Struct {
return errors.New("CopyProperties: param src should be a struct or struct pointer")
}
dstType, dstValue = dstType.Elem(), dstValue.Elem()
propertyNums := dstType.NumField()
for i := 0; i < propertyNums; i++ {
property := dstType.Field(i)
propertyValue := srcValue.FieldByName(property.Name)
if !propertyValue.IsValid() || property.Type != propertyValue.Type() {
continue
}
if dstValue.Field(i).CanSet() {
dstValue.Field(i).Set(propertyValue)
}
}
return nil
}