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  }