123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- package utils
- import (
- "errors"
- "reflect"
- )
- func DeepFields(ifaceType reflect.Type) []reflect.StructField {
- var fields []reflect.StructField
- for i := 0; i < ifaceType.NumField(); i++ {
- v := ifaceType.Field(i)
- if v.Anonymous && v.Type.Kind() == reflect.Struct {
- fields = append(fields, DeepFields(v.Type)...)
- } else {
- fields = append(fields, v)
- }
- }
- return fields
- }
- func StructCopy(DstStructPtr interface{}, SrcStructPtr interface{}) error {
- srcv := reflect.ValueOf(SrcStructPtr)
- dstv := reflect.ValueOf(DstStructPtr)
- srct := reflect.TypeOf(SrcStructPtr)
- dstt := reflect.TypeOf(DstStructPtr)
- if srct.Kind() != reflect.Ptr || dstt.Kind() != reflect.Ptr ||
- srct.Elem().Kind() == reflect.Ptr || dstt.Elem().Kind() == reflect.Ptr {
- return errors.New("Fatal error:type of parameters must be Ptr of value")
- }
- if srcv.IsNil() || dstv.IsNil() {
- return errors.New("Fatal error:value of parameters should not be nil")
- }
- srcV := srcv.Elem()
- dstV := dstv.Elem()
- srcfields := DeepFields(reflect.ValueOf(SrcStructPtr).Elem().Type())
- for _, v := range srcfields {
- if v.Anonymous {
- continue
- }
- dst := dstV.FieldByName(v.Name)
- src := srcV.FieldByName(v.Name)
- if !dst.IsValid() {
- continue
- }
- if src.Type() == dst.Type() && dst.CanSet() {
- dst.Set(src)
- continue
- }
- if src.Kind() == reflect.Ptr && !src.IsNil() && src.Type().Elem() == dst.Type() {
- dst.Set(src.Elem())
- continue
- }
- if dst.Kind() == reflect.Ptr && dst.Type().Elem() == src.Type() {
- dst.Set(reflect.New(src.Type()))
- dst.Elem().Set(src)
- continue
- }
- }
- return nil
- }
- func FieldByTag(value reflect.Value, tag string, tagName string) reflect.Value {
- itype := value.Type()
- for i := 0; i < itype.NumField(); i++ {
- v := itype.Field(i)
- if v.Tag.Get(tagName) == tag && tag != "" {
- return value.FieldByIndex(v.Index)
- }
- }
- return reflect.Value{}
- }
- func StructCopyByTag(DstStructPtr interface{}, SrcStructPtr interface{}, tagName string) error {
- srcv := reflect.ValueOf(SrcStructPtr)
- dstv := reflect.ValueOf(DstStructPtr)
- srct := reflect.TypeOf(SrcStructPtr)
- dstt := reflect.TypeOf(DstStructPtr)
- if srct.Kind() != reflect.Ptr || dstt.Kind() != reflect.Ptr ||
- srct.Elem().Kind() == reflect.Ptr || dstt.Elem().Kind() == reflect.Ptr {
- return errors.New("Fatal error:type of parameters must be Ptr of value")
- }
- if srcv.IsNil() || dstv.IsNil() {
- return errors.New("Fatal error:value of parameters should not be nil")
- }
- srcV := srcv.Elem()
- dstV := dstv.Elem()
- srcfields := DeepFields(reflect.ValueOf(SrcStructPtr).Elem().Type())
- for _, v := range srcfields {
- if v.Anonymous {
- continue
- }
- dst := FieldByTag(dstV, v.Tag.Get(tagName), tagName)
- src := FieldByTag(srcV, v.Tag.Get(tagName), tagName)
- if !dst.IsValid() {
- continue
- }
- if src.Type() == dst.Type() && dst.CanSet() {
- dst.Set(src)
- continue
- }
- if src.Kind() == reflect.Ptr && !src.IsNil() && src.Type().Elem() == dst.Type() {
- dst.Set(src.Elem())
- continue
- }
- if dst.Kind() == reflect.Ptr && dst.Type().Elem() == src.Type() {
- dst.Set(reflect.New(src.Type()))
- dst.Elem().Set(src)
- continue
- }
- }
- return nil
- }
|