2022-06-29 10:49:42 +00:00
|
|
|
package dynamic
|
|
|
|
|
|
|
|
import "reflect"
|
|
|
|
|
2022-06-30 04:37:54 +00:00
|
|
|
// MergeStructValues merges the field value from the source struct to the dest struct.
|
|
|
|
// Only fields with the same type and the same name will be updated.
|
2022-06-29 10:49:42 +00:00
|
|
|
func MergeStructValues(dst, src interface{}) {
|
2022-06-30 07:13:42 +00:00
|
|
|
if dst == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-06-29 10:49:42 +00:00
|
|
|
rtA := reflect.TypeOf(dst)
|
|
|
|
srcStructType := reflect.TypeOf(src)
|
|
|
|
|
|
|
|
rtA = rtA.Elem()
|
|
|
|
srcStructType = srcStructType.Elem()
|
|
|
|
|
|
|
|
for i := 0; i < rtA.NumField(); i++ {
|
|
|
|
fieldType := rtA.Field(i)
|
|
|
|
fieldName := fieldType.Name
|
2022-06-30 07:13:42 +00:00
|
|
|
|
|
|
|
if !fieldType.IsExported() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2022-06-30 04:37:54 +00:00
|
|
|
// if there is a field with the same name
|
2022-06-30 07:48:06 +00:00
|
|
|
fieldSrcType, found := srcStructType.FieldByName(fieldName)
|
|
|
|
if !found {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// ensure that the type is the same
|
|
|
|
if fieldSrcType.Type == fieldType.Type {
|
|
|
|
srcValue := reflect.ValueOf(src).Elem().FieldByName(fieldName)
|
|
|
|
dstValue := reflect.ValueOf(dst).Elem().FieldByName(fieldName)
|
|
|
|
if (fieldType.Type.Kind() == reflect.Ptr && dstValue.IsNil()) || dstValue.IsZero() {
|
|
|
|
dstValue.Set(srcValue)
|
2022-06-29 10:49:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|