github.com/litesolutions/justifay-api@v1.0.0-2.0.20220707114139-46f28a909481/internal/pkg/structs/merge.go (about) 1 package structs 2 3 import ( 4 "reflect" 5 ) 6 7 // Merge receives two structs, and merges them excluding fields with tag name: `structs`, value "-" 8 func Merge(dst, src interface{}) { 9 s := reflect.ValueOf(src) 10 d := reflect.ValueOf(dst) 11 if s.Kind() != reflect.Ptr || d.Kind() != reflect.Ptr { 12 return 13 } 14 for i := 0; i < s.Elem().NumField(); i++ { 15 v := s.Elem().Field(i) 16 fieldName := s.Elem().Type().Field(i).Name 17 skip := s.Elem().Type().Field(i).Tag.Get("structs") 18 if skip == "-" { 19 continue 20 } 21 if v.Kind() > reflect.Float64 && 22 v.Kind() != reflect.String && 23 v.Kind() != reflect.Struct && 24 v.Kind() != reflect.Ptr && 25 v.Kind() != reflect.Slice { 26 continue 27 } 28 if v.Kind() == reflect.Ptr { 29 // Field is pointer check if it's nil or set 30 if !v.IsNil() { 31 // Field is set assign it to dest 32 33 if d.Elem().FieldByName(fieldName).Kind() == reflect.Ptr { 34 d.Elem().FieldByName(fieldName).Set(v) 35 continue 36 } 37 f := d.Elem().FieldByName(fieldName) 38 if f.IsValid() { 39 f.Set(v.Elem()) 40 } 41 } 42 continue 43 } 44 d.Elem().FieldByName(fieldName).Set(v) 45 } 46 }