func GetEmbeddedField(object interface{}, nameOrType interface{}, dataTypes ...reflect.Kind) (field reflect.StructField) {
	if object == nil {
		return
	}
	typ, ok := GetObjectType(object)
	if ok {
		f, ok := GetEmbeddedFieldByType(typ, nameOrType, dataTypes...)
		if ok {
			field = f
		}
	}
	return
}
GetEmbeddedField get embedded interface field
package reflector
import (
	"errors"
	"hidevops.io/hiboot/pkg/utils/io"
	"hidevops.io/hiboot/pkg/utils/str"
	"reflect"
	"runtime"
	"strings"
)
var (
	ErrInvalidInput = errors.New("input is invalid")
	ErrInvalidMethod = errors.New("method is invalid")
	ErrInvalidFunc = errors.New("func is invalid")
	ErrFieldCanNotBeSet = errors.New("field can not be set")
)
func NewReflectType(st interface{}) interface{} {
	ct := reflect.TypeOf(st)
	co := reflect.New(ct)
	cp := co.Elem().Addr().Interface()
	return cp
}
func Validate(toValue interface{}) (*reflect.Value, error) {
	to := Indirect(reflect.ValueOf(toValue))
	if !to.IsValid() {
		return nil, errors.New("value is not valid")
	}
	if !to.CanAddr() {
		return nil, errors.New("value is unaddressable")
	}
	return &to, nil
}
func DeepFields(reflectType reflect.Type) []reflect.StructField {
	var fields []reflect.StructField
	if reflectType = IndirectType(reflectType); reflectType.Kind() == reflect.Struct {
		for i := 0; i < reflectType.NumField(); i++ {
			v := reflectType.Field(i)
			if v.Anonymous {
				vk :=  IndirectType(v.Type).Kind()
				if vk != reflect.Struct && vk != reflect.Interface {
					fields = append(fields, v)
				} else {
					fields = append(fields, DeepFields(v.Type)...)
				}
			} else {
				fields = append(fields, v)
			}
		}
	}
	return fields
}
func Indirect(reflectValue reflect.Value) reflect.Value {
	for reflectValue.Kind() == reflect.Ptr {
		reflectValue = reflectValue.Elem()
	}
	return reflectValue
}
func IndirectValue(object interface{}) (reflectValue reflect.Value) {
	switch object.(type) {
	case reflect.Value:
		reflectValue = object.(reflect.Value)
	case reflect.Type:
		return
	default:
		reflectValue = reflect.ValueOf(object)
	}
	reflectValue = Indirect(reflectValue)
	return
}
func IndirectType(reflectType reflect.Type) reflect.Type {
	for reflectType.Kind() == reflect.Ptr || reflectType.Kind() == reflect.Slice {
		reflectType = reflectType.Elem()
	}
	return reflectType
}
func GetFieldValue(f interface{}, name string) reflect.Value {
	r := reflect.ValueOf(f)
	fv := reflect.Indirect(r).FieldByName(name)
	return fv
}
func FindFieldByTag(obj interface{}, key, name string) (field reflect.StructField, ok bool) {
	typ, ok := GetObjectType(obj)
	if ok {
		for _, f := range DeepFields(typ) {
			if f.Tag.Get(key) == name {
				field = f
				ok = true
				break
			}
		}
	}
	return
}
func SetFieldValue(object interface{}, name string, value interface{}) error {
	obj := Indirect(reflect.ValueOf(object))
	if !obj.IsValid() {
		return ErrInvalidInput
	}
	if obj.Kind() != reflect.Struct {
		return ErrInvalidInput
	}
	fieldObj := obj.FieldByName(name)
	if !fieldObj.CanSet() {
		return ErrFieldCanNotBeSet
	}
	fov := reflect.ValueOf(value)
	fieldObj.Set(fov)
	return nil
}
func GetKind(kind reflect.Kind) reflect.Kind {
	switch {
	case kind >= reflect.Int && kind <= reflect.Int64:
		return reflect.Int
	case kind >= reflect.Uint && kind <= reflect.Uint64:
		return reflect.Uint
	case kind >= reflect.Float32 && kind <= reflect.Float64:
		return reflect.Float32
	default:
		return kind
	}
}
func GetKindByValue(val reflect.Value) reflect.Kind {
	return GetKind(val.Kind())
}
func GetKindByType(typ reflect.Type) reflect.Kind {
	return GetKind(typ.Kind())
}
func ValidateReflectType(obj interface{}, callback func(value *reflect.Value, reflectType reflect.Type, fieldSize int, isSlice bool) error) error {
	v, err := Validate(obj)
	if err != nil {
		return err
	}
	t := IndirectType(v.Type())
	isSlice := false
	fieldSize := 1
	if v.Kind() == reflect.Slice {
		isSlice = true
		fieldSize = v.Len()
	}
	if callback != nil {
		return callback(v, t, fieldSize, isSlice)
	}
	return err
}
func GetType(data interface{}) (typ reflect.Type, err error) {
	dv := Indirect(reflect.ValueOf(data))
	if !dv.IsValid() {
		err = ErrInvalidInput
		return
	}
	typ = dv.Type()
	return
}
func parseFuncName(name string) string {
	n := strings.LastIndexByte(name, byte('.'))
	if n > 0 {
		name = name[n+1:]
		n = strings.LastIndexByte(name, byte('-'))
		if n > 0 {
			name = name[:n]
		}
		n = strings.LastIndexByte(name, byte(')'))
		if n > 0 {
			name = name[:n]
		}
	}
	return name
}
func GetFuncName(fn interface{}) (name string) {
	val := reflect.ValueOf(fn)
	kind := val.Kind()
	if kind == reflect.Func {
		name = runtime.FuncForPC(val.Pointer()).Name()
		name = parseFuncName(name)
	}
	return
}
func GetName(data interface{}) (name string) {
	typ, err := GetType(data)
	if err == nil {
		name = typ.Name()
	}
	return
}
func GetLowerCamelName(object interface{}) (name string) {
	name = GetName(object)
	name = str.ToLowerCamel(name)
	return name
}
func HasField(object interface{}, name string) bool {
	r := reflect.ValueOf(object)
	fv := reflect.Indirect(r).FieldByName(name)
	return fv.IsValid()
}
func CallMethodByName(object interface{}, name string, args ...interface{}) (interface{}, error) {
	objVal := reflect.ValueOf(object)
	method, ok := objVal.Type().MethodByName(name)
	if ok {
		numIn := method.Type.NumIn()
		inputs := make([]reflect.Value, numIn)
		inputs[0] = objVal
		for i, arg := range args {
			inputs[i+1] = reflect.ValueOf(arg)
		}
		results := method.Func.Call(inputs)
		if len(results) != 0 {
			return results[0].Interface(), nil
		}
		return nil, nil
	}
	return nil, ErrInvalidMethod
}
func CallFunc(object interface{}, args ...interface{}) (interface{}, error) {
	fn := reflect.ValueOf(object)
	if fn.Kind() == reflect.Func {
		numIn := fn.Type().NumIn()
		inputs := make([]reflect.Value, numIn)
		for i, arg := range args {
			inputs[i] = reflect.ValueOf(arg)
		}
		results := fn.Call(inputs)
		if len(results) != 0 {
			return results[0].Interface(), nil
		}
		return nil, nil
	}
	return nil, ErrInvalidFunc
}
func HasEmbeddedField(object interface{}, name string) bool {
	typ := IndirectType(reflect.TypeOf(object))
	if typ.Kind() != reflect.Struct {
		return false
	}
	field, ok := typ.FieldByName(name)
	return field.Anonymous && ok
}
func GetEmbeddedFieldType(object interface{}, expected interface{}) (field reflect.StructField, ok bool) {
	if object == nil {
		return
	}
	typ, got := GetObjectType(object)
	if got {
		expectedTyp, _ := GetObjectType(expected)
		field, ok = GetEmbeddedFieldByType(typ, expectedTyp.Name(), expectedTyp.Kind())
	}
	return
}
func HasEmbeddedFieldType(object interface{}, expected interface{}) (found bool) {
	_, found = GetEmbeddedFieldType(object, expected)
	return
}
func GetEmbeddedFieldByType(typ reflect.Type, nameOrType interface{}, kind ...reflect.Kind) (field reflect.StructField, ok bool) {
	expectedKind := reflect.Interface
	if len(kind) > 0 {
		expectedKind = kind[0]
	}
	var name string
	switch nameOrType.(type) {
	case string:
		name = nameOrType.(string)
	default:
		name = GetName(nameOrType)
	}
	k := typ.Kind()
	if k == reflect.Struct {
		numField := typ.NumField()
		for i := 0; i < numField; i++ {
			v := typ.Field(i)
			if v.Anonymous {
				if v.Type.Kind() == expectedKind && (name == "" || v.Name == name) {
					field = v
					ok = true
					break
				} else {
					field, ok = GetEmbeddedFieldByType(v.Type, name, kind...)
					if ok {
						break
					}
				}
			}
		}
	}
	return
}
func GetEmbeddedFieldsByType(typ reflect.Type, kind ...reflect.Kind) (fields []reflect.StructField) {
	expectedKind := reflect.Interface
	if len(kind) > 0 {
		expectedKind = kind[0]
	}
	if typ == nil {
		return
	}
	k := typ.Kind()
	if k == reflect.Struct {
		numField := typ.NumField()
		for i := 0; i < numField; i++ {
			v := typ.Field(i)
			if v.Anonymous {
				if v.Type.Kind() == expectedKind {
					fields = append(fields, v)
				} else {
					f := GetEmbeddedFieldsByType(v.Type)
					fields = append(fields, f...)
				}
			}
		}
	}
	return
}
func GetEmbeddedFields(object interface{}, kind ...reflect.Kind) (fields []reflect.StructField) {
	if object == nil {
		return
	}
	typ, _ := GetObjectType(object)
	fields = GetEmbeddedFieldsByType(typ, kind...)
	return
}