2020-06-05 19:15:07 +08:00
|
|
|
// Package structs is for manipulating structures with reflection
|
|
|
|
package structs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
)
|
|
|
|
|
|
|
|
// SetFrom sets the public members of a from b
|
|
|
|
//
|
|
|
|
// a and b should be pointers to structs
|
|
|
|
//
|
|
|
|
// a can be a different type from b
|
|
|
|
//
|
|
|
|
// Only the Fields which have the same name and assignable type on a
|
|
|
|
// and b will be set.
|
|
|
|
//
|
|
|
|
// This is useful for copying between almost identical structures that
|
Spelling fixes
Fix spelling of: above, already, anonymous, associated,
authentication, bandwidth, because, between, blocks, calculate,
candidates, cautious, changelog, cleaner, clipboard, command,
completely, concurrently, considered, constructs, corrupt, current,
daemon, dependencies, deprecated, directory, dispatcher, download,
eligible, ellipsis, encrypter, endpoint, entrieslist, essentially,
existing writers, existing, expires, filesystem, flushing, frequently,
hierarchy, however, implementation, implements, inaccurate,
individually, insensitive, longer, maximum, metadata, modified,
multipart, namedirfirst, nextcloud, obscured, opened, optional,
owncloud, pacific, passphrase, password, permanently, persimmon,
positive, potato, protocol, quota, receiving, recommends, referring,
requires, revisited, satisfied, satisfies, satisfy, semver,
serialized, session, storage, strategies, stringlist, successful,
supported, surprise, temporarily, temporary, transactions, unneeded,
update, uploads, wrapped
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2020-10-09 08:17:24 +08:00
|
|
|
// are frequently present in auto generated code for cloud storage
|
2020-06-05 19:15:07 +08:00
|
|
|
// interfaces.
|
|
|
|
func SetFrom(a, b interface{}) {
|
|
|
|
ta := reflect.TypeOf(a).Elem()
|
|
|
|
tb := reflect.TypeOf(b).Elem()
|
|
|
|
va := reflect.ValueOf(a).Elem()
|
|
|
|
vb := reflect.ValueOf(b).Elem()
|
|
|
|
for i := 0; i < tb.NumField(); i++ {
|
|
|
|
bField := vb.Field(i)
|
|
|
|
tbField := tb.Field(i)
|
|
|
|
name := tbField.Name
|
|
|
|
aField := va.FieldByName(name)
|
|
|
|
taField, found := ta.FieldByName(name)
|
|
|
|
if found && aField.IsValid() && bField.IsValid() && aField.CanSet() && tbField.Type.AssignableTo(taField.Type) {
|
|
|
|
aField.Set(bField)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetDefaults for a from b
|
|
|
|
//
|
|
|
|
// a and b should be pointers to the same kind of struct
|
|
|
|
//
|
|
|
|
// This copies the public members only from b to a. This is useful if
|
|
|
|
// you can't just use a struct copy because it contains a private
|
2020-10-14 05:49:58 +08:00
|
|
|
// mutex, e.g. as http.Transport.
|
2020-06-05 19:15:07 +08:00
|
|
|
func SetDefaults(a, b interface{}) {
|
|
|
|
pt := reflect.TypeOf(a)
|
|
|
|
t := pt.Elem()
|
|
|
|
va := reflect.ValueOf(a).Elem()
|
|
|
|
vb := reflect.ValueOf(b).Elem()
|
|
|
|
for i := 0; i < t.NumField(); i++ {
|
|
|
|
aField := va.Field(i)
|
|
|
|
// Set a from b if it is public
|
|
|
|
if aField.CanSet() {
|
|
|
|
bField := vb.Field(i)
|
|
|
|
aField.Set(bField)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|