diamond-orm/util.go

104 lines
2.3 KiB
Go

package orm
import (
"fmt"
"reflect"
"strings"
)
func panik(err error) {
if err != nil {
panic(err)
}
}
func nameOf(i interface{}) string {
v := reflect.ValueOf(i)
var n string
switch v.Kind() {
case reflect.Slice, reflect.Map:
if v.Type().Elem().Kind() == reflect.Pointer {
n = v.Type().Elem().Elem().Name()
}
case reflect.Pointer:
n = nameOf(reflect.Indirect(v).Interface())
default:
n = v.Type().Name()
}
return n
}
func valueOf(i interface{}) reflect.Value {
v := reflect.ValueOf(i)
if v.Type().Kind() == reflect.Slice || v.Type().Kind() == reflect.Map {
in := v.Type().Elem()
switch in.Kind() {
case reflect.Pointer:
v = reflect.New(in.Elem()).Elem()
default:
v = reflect.New(in).Elem()
}
} else if v.Type().Kind() == reflect.Pointer {
v = valueOf(reflect.Indirect(v).Interface())
}
return v
}
func iFace(input interface{}) interface{} {
return reflect.ValueOf(input).Interface()
}
func iFaceSlice(input interface{}) []interface{} {
ret := make([]interface{}, 0)
fv := reflect.ValueOf(input)
if fv.Type().Kind() != reflect.Slice {
return ret
}
for i := 0; i < fv.Len(); i++ {
ret = append(ret, fv.Index(i).Interface())
}
return ret
}
func coerceInt(input reflect.Value, dst reflect.Value) interface{} {
if input.Type().Kind() == reflect.Pointer {
input = input.Elem()
}
if dst.Type().Kind() == reflect.Pointer {
dst = dst.Elem()
}
if input.Type().ConvertibleTo(dst.Type()) {
return input.Convert(dst.Type()).Interface()
}
return nil
}
func getNested(field string, value reflect.Value) (*reflect.Type, *reflect.Value, error) {
if strings.HasPrefix(field, ".") || strings.HasSuffix(field, ".") {
return nil, nil, fmt.Errorf("Malformed field name %s passed", field)
}
dots := strings.Split(field, ".")
if value.Kind() != reflect.Struct {
return nil, nil, fmt.Errorf("This value is not a struct!")
}
ref := value
if ref.Kind() == reflect.Pointer {
ref = ref.Elem()
}
fv := ref.FieldByName(dots[0])
ft := fv.Type()
if len(dots) > 1 {
return getNested(strings.Join(dots[1:], "."), fv)
} else {
return &ft, &fv, nil
}
}
func makeSettable(rval reflect.Value, value interface{}) reflect.Value {
if !rval.CanSet() {
nv := reflect.New(rval.Type())
nv.Elem().Set(reflect.ValueOf(value))
return nv
}
return rval
}