func (p *MethodMetadata) IsEqual(t reflect.Type) bool { if t.ConvertibleTo(p.Method.Type) { return false } baseIndex := 0 if p.Method.Index >= 0 { baseIndex = 1 } if t.NumIn()+baseIndex != p.Method.Type.NumIn() { return false } for i := 0; i < p.Method.Type.NumIn()-baseIndex; i++ { if p.Method.Type.In(baseIndex+i) != t.In(i) { return false } } for i := 0; i < p.Method.Type.NumOut(); i++ { if p.Method.Type.Out(baseIndex+i) != t.Out(i) { return false } } return true }
func (h funcHandler) HandleEvent(typ reflect.Type, val reflect.Value) { if typ == nil { h.fn.Call([]reflect.Value{}) } else if typ.ConvertibleTo(h.typ) { h.fn.Call([]reflect.Value{val}) } }
// Run recevies the argument and func (m *mqueSub) Run(d interface{}, ctype reflect.Type) { if !m.has { for _, tm := range m.tms { tm.Call([]reflect.Value{}) } return } var configVal reflect.Value if !ctype.AssignableTo(m.am) { if !ctype.ConvertibleTo(m.am) { return } vum := reflect.ValueOf(d) configVal = vum.Convert(m.am) } else { configVal = reflect.ValueOf(d) } for _, tm := range m.tms { tm.Call([]reflect.Value{configVal}) } }
// Short returns a unique (in the current scope) name for the argument of type t. func (opts *GenOpts) Short(t reflect.Type, cur map[string]struct{}) string { tt := t for tt.Kind() == reflect.Ptr || tt.Kind() == reflect.Slice { tt = tt.Elem() } pkg, name := packageAndName(tt) f := opts.First(name) // First letter. // Handle common types. switch { case t.ConvertibleTo(errorType): f = "err" case t.ConvertibleTo(ctxType): f = "ctx" default: n, clean := opts.lowerName(name) // Very short names. if len(n) <= 3 && string(n) != clean && string(n) != pkg { f = string(n) } } // Make sure the name is unique. name = f for c := 1; ; c++ { if _, ok := cur[name]; !ok { // Update the set of currently used names. cur[name] = struct{}{} return name } name = fmt.Sprintf("%s%d", f, c) } }
func mustBeCompatible(a, b reflect.Type) { if !a.ConvertibleTo(b) || !a.AssignableTo(b) { panic(errors.New(fmt.Sprintf( "Types '%v' and '%v' is not compatile to each other! "+ "It is no possible to make a swap function that "+ "return or receive different kinds of objects!", a.Name(), b.Name()))) } }
func isNumberType(t reflect.Type) bool { for _, nt := range numberTypes { if t.ConvertibleTo(nt) { return true } } return false }
// CanSetForType checks if a val reflect.Type can be used for the target type. // It returns true bool, where the first returns if the value can be used and if // it must be converted into the type first. func CanSetForType(target, val reflect.Type) (canSet bool, mustConvert bool) { if val.AssignableTo(target) { canSet = true return } if val.ConvertibleTo(target) { canSet = true mustConvert = true return } return }
func unmarshalToType(typ reflect.Type, value string) (val interface{}, err error) { // If we get a pointer in, we'll return a pointer out if typ.Kind() == reflect.Ptr { val = reflect.New(typ.Elem()).Interface() } else { val = reflect.New(typ).Interface() } defer func() { if err == nil && typ.Kind() != reflect.Ptr { val = reflect.Indirect(reflect.ValueOf(val)).Interface() } }() // If we can just assign the value, return the value if typ.AssignableTo(reflect.TypeOf(value)) { return value, nil } // Try Unmarshalers if um, ok := val.(encoding.TextUnmarshaler); ok { if err = um.UnmarshalText([]byte(value)); err == nil { return val, nil } } if um, ok := val.(json.Unmarshaler); ok { if err = um.UnmarshalJSON([]byte(value)); err == nil { return val, nil } } // Try conversion if typ.ConvertibleTo(reflect.TypeOf(value)) { return reflect.ValueOf(value).Convert(typ).Interface(), nil } // Try JSON if err = json.Unmarshal([]byte(value), val); err == nil { return val, nil } // Return error if we have one if err != nil { return nil, err } return val, fmt.Errorf("No way to unmarshal \"%s\" to %s", value, typ.Name()) }
func (s *schemaField) check(ft reflect.Type, v interface{}) error { t := reflect.TypeOf(v) if !ft.AssignableTo(t) { if !ft.ConvertibleTo(t) { return fmt.Errorf("type %s (%v) cannot be converted to %T", ft.Name(), ft.Kind(), t.Name()) } s.marshalType = t } if !t.AssignableTo(ft) { if !t.ConvertibleTo(ft) { return fmt.Errorf("type %s (%v) cannot be converted to %T", t.Name(), t.Kind(), ft.Name()) } s.unmarshalType = ft } return nil }
func Type2SQLType(t reflect.Type) (st SQLType) { switch k := t.Kind(); k { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32: st = SQLType{Int, 0, 0} case reflect.Int64, reflect.Uint64: st = SQLType{BigInt, 0, 0} case reflect.Float32: st = SQLType{Float, 0, 0} case reflect.Float64: st = SQLType{Double, 0, 0} case reflect.Complex64, reflect.Complex128: st = SQLType{Varchar, 64, 0} case reflect.Array, reflect.Slice, reflect.Map: if t.Elem() == reflect.TypeOf(c_BYTE_DEFAULT) { st = SQLType{Blob, 0, 0} } else { st = SQLType{Text, 0, 0} } case reflect.Bool: st = SQLType{Bool, 0, 0} case reflect.String: st = SQLType{Varchar, 255, 0} case reflect.Struct: if t.ConvertibleTo(reflect.TypeOf(c_TIME_DEFAULT)) { st = SQLType{DateTime, 0, 0} } else { // TODO need to handle association struct st = SQLType{Text, 0, 0} } case reflect.Ptr: st, _ = ptrType2SQLType(t) default: st = SQLType{Text, 0, 0} } return }
func implements(wanted, source reflect.Type) bool { return source.ConvertibleTo(wanted) }
func visible(wanted reflect.Type, mask reflect.Type) bool { return mask.ConvertibleTo(wanted) }
func skipTextMarshalling(t reflect.Type) bool { /*// Skip time.Time because its text unmarshaling is overly rigid: return t == timeType || t == timePtrType*/ // Skip time.Time & convertibles because its text unmarshaling is overly rigid: return t.ConvertibleTo(timeType) || t.ConvertibleTo(timePtrType) }
func (h chanHandler) HandleEvent(typ reflect.Type, val reflect.Value) { if typ.ConvertibleTo(typ) { h.ch.TrySend(val) } }
func tyvarName(t reflect.Type) string { if !t.ConvertibleTo(tyvarUnderlyingType) { return "" } return t.Name() }
// convert tries to convert rv from the source type to destination type. // Returns an error if this fails. This applies the numerous type conversions // we need to support when going between NBT and Go data. // // Refer to the "Type compatibility" section in the `nbt` package README. func convert(rv reflect.Value, dst, src reflect.Type) (reflect.Value, error) { if src.ConvertibleTo(dst) { return rv.Convert(dst), nil } switch src.Kind() { case reflect.Slice: if dst.Kind() != reflect.Slice { break } switch src.Elem().Kind() { case reflect.Int8: v := rv.Interface().([]int8) switch dst.Elem().Kind() { case reflect.Uint8: if len(v) == 0 { return reflect.ValueOf(([]uint8)(nil)), nil } ptr := (*(*[1<<31 - 1]uint8)(unsafe.Pointer(&v[0])))[:len(v)] return reflect.ValueOf(ptr), nil } case reflect.Uint8: v := rv.Interface().([]uint8) switch dst.Elem().Kind() { case reflect.Int8: if len(v) == 0 { return reflect.ValueOf(([]int8)(nil)), nil } ptr := (*(*[1<<31 - 1]int8)(unsafe.Pointer(&v[0])))[:len(v)] return reflect.ValueOf(ptr), nil } case reflect.Int32: v := rv.Interface().([]int32) switch dst.Elem().Kind() { case reflect.Uint32: if len(v) == 0 { return reflect.ValueOf(([]uint32)(nil)), nil } ptr := (*(*[1<<31 - 1]uint32)(unsafe.Pointer(&v[0])))[:len(v)] return reflect.ValueOf(ptr), nil } case reflect.Uint32: v := rv.Interface().([]uint32) switch dst.Elem().Kind() { case reflect.Int32: if len(v) == 0 { return reflect.ValueOf(([]int32)(nil)), nil } ptr := (*(*[1<<31 - 1]int32)(unsafe.Pointer(&v[0])))[:len(v)] return reflect.ValueOf(ptr), nil } } case reflect.String: v := rv.String() switch dst.Kind() { case reflect.Bool: b, err := strconv.ParseBool(v) if err == nil { return reflect.ValueOf(b), nil } } case reflect.Int8: v := rv.Interface().(int8) switch dst.Kind() { case reflect.Bool: return reflect.ValueOf(v != 0), nil case reflect.Uint8: return reflect.ValueOf(uint8(v)), nil case reflect.Int16: return reflect.ValueOf(int16(v)), nil case reflect.Uint16: return reflect.ValueOf(uint16(v)), nil case reflect.Int32: return reflect.ValueOf(int32(v)), nil case reflect.Uint32: return reflect.ValueOf(uint32(v)), nil case reflect.Int64: return reflect.ValueOf(int64(v)), nil case reflect.Uint64: return reflect.ValueOf(uint64(v)), nil } case reflect.Int16: v := rv.Interface().(int16) switch dst.Kind() { case reflect.Uint16: return reflect.ValueOf(uint16(v)), nil case reflect.Int32: return reflect.ValueOf(int32(v)), nil case reflect.Uint32: return reflect.ValueOf(uint16(v)), nil case reflect.Int64: return reflect.ValueOf(int64(v)), nil case reflect.Uint64: return reflect.ValueOf(uint64(v)), nil } case reflect.Int32: v := rv.Interface().(int32) switch dst.Kind() { case reflect.Uint32: return reflect.ValueOf(uint32(v)), nil case reflect.Int64: return reflect.ValueOf(int64(v)), nil case reflect.Uint64: return reflect.ValueOf(uint64(v)), nil } case reflect.Int64: v := rv.Interface().(int64) switch dst.Kind() { case reflect.Struct: if dst.Name() == "Time" { return reflect.ValueOf(time.Unix(v, 0)), nil } case reflect.Uint64: return reflect.ValueOf(uint64(v)), nil } case reflect.Float32: v := rv.Interface().(float32) switch dst.Kind() { case reflect.Float64: return reflect.ValueOf(float64(v)), nil } } return rv, fmt.Errorf("can not convert %v(%v) to %v", src, rv.Interface(), dst) }