github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/lib/structs/structs.go (about) 1 // Package structs is for manipulating structures with reflection 2 package structs 3 4 import ( 5 "reflect" 6 ) 7 8 // SetFrom sets the public members of a from b 9 // 10 // a and b should be pointers to structs 11 // 12 // a can be a different type from b 13 // 14 // Only the Fields which have the same name and assignable type on a 15 // and b will be set. 16 // 17 // This is useful for copying between almost identical structures that 18 // are requently present in auto generated code for cloud storage 19 // interfaces. 20 func SetFrom(a, b interface{}) { 21 ta := reflect.TypeOf(a).Elem() 22 tb := reflect.TypeOf(b).Elem() 23 va := reflect.ValueOf(a).Elem() 24 vb := reflect.ValueOf(b).Elem() 25 for i := 0; i < tb.NumField(); i++ { 26 bField := vb.Field(i) 27 tbField := tb.Field(i) 28 name := tbField.Name 29 aField := va.FieldByName(name) 30 taField, found := ta.FieldByName(name) 31 if found && aField.IsValid() && bField.IsValid() && aField.CanSet() && tbField.Type.AssignableTo(taField.Type) { 32 aField.Set(bField) 33 } 34 } 35 } 36 37 // SetDefaults for a from b 38 // 39 // a and b should be pointers to the same kind of struct 40 // 41 // This copies the public members only from b to a. This is useful if 42 // you can't just use a struct copy because it contains a private 43 // mutex, eg as http.Transport. 44 func SetDefaults(a, b interface{}) { 45 pt := reflect.TypeOf(a) 46 t := pt.Elem() 47 va := reflect.ValueOf(a).Elem() 48 vb := reflect.ValueOf(b).Elem() 49 for i := 0; i < t.NumField(); i++ { 50 aField := va.Field(i) 51 // Set a from b if it is public 52 if aField.CanSet() { 53 bField := vb.Field(i) 54 aField.Set(bField) 55 } 56 } 57 }