aboutsummaryrefslogtreecommitdiffstats
path: root/proptools/proptools.go
diff options
context:
space:
mode:
Diffstat (limited to 'proptools/proptools.go')
-rw-r--r--proptools/proptools.go164
1 files changed, 0 insertions, 164 deletions
diff --git a/proptools/proptools.go b/proptools/proptools.go
index e761926..79c4f6d 100644
--- a/proptools/proptools.go
+++ b/proptools/proptools.go
@@ -15,7 +15,6 @@
package proptools
import (
- "fmt"
"reflect"
"strings"
"unicode"
@@ -40,169 +39,6 @@ func FieldNameForProperty(propertyName string) string {
return fieldName
}
-func CloneProperties(structValue reflect.Value) reflect.Value {
- result := reflect.New(structValue.Type())
- CopyProperties(result.Elem(), structValue)
- return result
-}
-
-func CopyProperties(dstValue, srcValue reflect.Value) {
- typ := dstValue.Type()
- if srcValue.Type() != typ {
- panic(fmt.Errorf("can't copy mismatching types (%s <- %s)",
- dstValue.Kind(), srcValue.Kind()))
- }
-
- for i := 0; i < srcValue.NumField(); i++ {
- field := typ.Field(i)
- if field.PkgPath != "" {
- // The field is not exported so just skip it.
- continue
- }
-
- srcFieldValue := srcValue.Field(i)
- dstFieldValue := dstValue.Field(i)
-
- switch srcFieldValue.Kind() {
- case reflect.Bool, reflect.String, reflect.Int, reflect.Uint:
- dstFieldValue.Set(srcFieldValue)
- case reflect.Struct:
- CopyProperties(dstFieldValue, srcFieldValue)
- case reflect.Slice:
- if !srcFieldValue.IsNil() {
- if field.Type.Elem().Kind() != reflect.String {
- panic(fmt.Errorf("can't copy field %q: slice elements are "+
- "not strings", field.Name))
- }
- if srcFieldValue != dstFieldValue {
- newSlice := reflect.MakeSlice(field.Type, srcFieldValue.Len(),
- srcFieldValue.Len())
- reflect.Copy(newSlice, srcFieldValue)
- dstFieldValue.Set(newSlice)
- }
- } else {
- dstFieldValue.Set(srcFieldValue)
- }
- case reflect.Ptr, reflect.Interface:
- if !srcFieldValue.IsNil() {
- if dstFieldValue.IsNil() ||
- dstFieldValue.Type() != srcFieldValue.Type() {
-
- // We can't use the existing destination allocation, so
- // clone a new one.
- elem := srcFieldValue.Elem()
- if srcFieldValue.Kind() == reflect.Interface {
- if elem.Kind() != reflect.Ptr {
- panic(fmt.Errorf("can't clone field %q: interface "+
- "refers to a non-pointer", field.Name))
- }
- elem = elem.Elem()
- }
- if elem.Kind() != reflect.Struct {
- panic(fmt.Errorf("can't clone field %q: points to a "+
- "non-struct", field.Name))
- }
- dstFieldValue.Set(CloneProperties(elem))
- } else {
- // Re-use the existing allocation.
- CopyProperties(dstFieldValue.Elem().Elem(), srcFieldValue.Elem().Elem())
- }
- } else {
- dstFieldValue.Set(srcFieldValue)
- }
- default:
- panic(fmt.Errorf("unexpected kind for property struct field %q: %s",
- field.Name, srcFieldValue.Kind()))
- }
- }
-}
-
-func ZeroProperties(structValue reflect.Value) {
- typ := structValue.Type()
-
- for i := 0; i < structValue.NumField(); i++ {
- field := typ.Field(i)
- if field.PkgPath != "" {
- // The field is not exported so just skip it.
- continue
- }
-
- fieldValue := structValue.Field(i)
-
- switch fieldValue.Kind() {
- case reflect.Bool, reflect.String, reflect.Struct, reflect.Slice, reflect.Int, reflect.Uint:
- fieldValue.Set(reflect.Zero(fieldValue.Type()))
- case reflect.Ptr, reflect.Interface:
- if !fieldValue.IsNil() {
- // We leave the pointer intact and zero out the struct that's
- // pointed to.
- elem := fieldValue.Elem()
- if fieldValue.Kind() == reflect.Interface {
- if elem.Kind() != reflect.Ptr {
- panic(fmt.Errorf("can't zero field %q: interface "+
- "refers to a non-pointer", field.Name))
- }
- elem = elem.Elem()
- }
- if elem.Kind() != reflect.Struct {
- panic(fmt.Errorf("can't zero field %q: points to a "+
- "non-struct", field.Name))
- }
- ZeroProperties(elem)
- }
- default:
- panic(fmt.Errorf("unexpected kind for property struct field %q: %s",
- field.Name, fieldValue.Kind()))
- }
- }
-}
-
-func CloneEmptyProperties(structValue reflect.Value) reflect.Value {
- result := reflect.New(structValue.Type())
- cloneEmptyProperties(result.Elem(), structValue)
- return result
-}
-
-func cloneEmptyProperties(dstValue, srcValue reflect.Value) {
- typ := srcValue.Type()
- for i := 0; i < srcValue.NumField(); i++ {
- field := typ.Field(i)
- if field.PkgPath != "" {
- // The field is not exported so just skip it.
- continue
- }
-
- srcFieldValue := srcValue.Field(i)
- dstFieldValue := dstValue.Field(i)
-
- switch srcFieldValue.Kind() {
- case reflect.Bool, reflect.String, reflect.Slice, reflect.Int, reflect.Uint:
- // Nothing
- case reflect.Struct:
- cloneEmptyProperties(dstFieldValue, srcFieldValue)
- case reflect.Ptr, reflect.Interface:
- if !srcFieldValue.IsNil() {
- elem := srcFieldValue.Elem()
- if srcFieldValue.Kind() == reflect.Interface {
- if elem.Kind() != reflect.Ptr {
- panic(fmt.Errorf("can't clone field %q: interface "+
- "refers to a non-pointer", field.Name))
- }
- elem = elem.Elem()
- }
- if elem.Elem().Kind() != reflect.Struct {
- panic(fmt.Errorf("can't clone field %q: points to a "+
- "non-struct", field.Name))
- }
- dstFieldValue.Set(CloneEmptyProperties(elem.Elem()))
- }
- default:
- panic(fmt.Errorf("unexpected kind for property struct field %q: %s",
- field.Name, srcFieldValue.Kind()))
- }
- }
-}
-
func HasTag(field reflect.StructField, name, value string) bool {
tag := field.Tag.Get(name)
for _, entry := range strings.Split(tag, ",") {