From 01cc315e25b38331c0a366d8025600ed4e297e8e Mon Sep 17 00:00:00 2001 From: crusader Date: Wed, 22 Aug 2018 17:59:12 +0900 Subject: [PATCH] json, reflect added --- encoding/json/json.go | 54 ++ encoding/json/number.go | 14 + reflect/convert.go | 1153 +++++++++++++++++++++++++++++++++++++++ reflect/error.go | 41 ++ reflect/indirect.go | 31 ++ reflect/kind.go | 35 ++ reflect/type.go | 72 +++ 7 files changed, 1400 insertions(+) create mode 100644 encoding/json/json.go create mode 100644 encoding/json/number.go create mode 100644 reflect/convert.go create mode 100644 reflect/error.go create mode 100644 reflect/indirect.go create mode 100644 reflect/kind.go create mode 100644 reflect/type.go diff --git a/encoding/json/json.go b/encoding/json/json.go new file mode 100644 index 0000000..22893b3 --- /dev/null +++ b/encoding/json/json.go @@ -0,0 +1,54 @@ +package json + +import ( + "encoding/json" + "fmt" + "reflect" + + our "git.loafle.net/overflow/util-go/reflect" +) + +// SetValueWithJSONStringArray set the value of json string array +// raw([]byte) is ["1", {"a": 1}, [1, 2]] +// targets([]interface{}) is array of pointer ex) *int, *string, *[], *map, *struct +func SetValueWithJSONStringArrayBytes(raw []byte, targets []interface{}) error { + var values []string + if err := json.Unmarshal(raw, &values); err != nil { + return err + } + + return SetValueWithJSONStringArray(values, targets) +} + +func SetValueWithJSONStringArray(values []string, targets []interface{}) error { + if len(targets) != len(values) { + return fmt.Errorf("Count of raw[%d] and targets[%d] is not same", len(values), len(targets)) + } + + for indexI := 0; indexI < len(values); indexI++ { + target := targets[indexI] + value := values[indexI] + + if reflect.Ptr != reflect.TypeOf(target).Kind() { + return fmt.Errorf("Type of target[%d] must be ptr but is %s, value=%s", indexI, reflect.TypeOf(target).Kind(), value) + } + + switch reflect.TypeOf(target).Elem().Kind() { + case reflect.Array, reflect.Slice, reflect.Map, reflect.Struct: + if err := json.Unmarshal([]byte(value), &target); nil != err { + return err + } + case reflect.Ptr: + return fmt.Errorf("Type of target[%d] cannot be double ptr, value=%s", indexI, value) + default: + cv, err := our.ConvertToType(value, reflect.TypeOf(target).Elem()) + if nil != err { + return fmt.Errorf("Type conversion of value[%s] has been failed to %s[%d]", value, reflect.TypeOf(target).Elem().Kind(), indexI) + } + + reflect.ValueOf(target).Elem().Set(reflect.ValueOf(cv)) + } + } + + return nil +} diff --git a/encoding/json/number.go b/encoding/json/number.go new file mode 100644 index 0000000..936ba86 --- /dev/null +++ b/encoding/json/number.go @@ -0,0 +1,14 @@ +package json + +import ( + "encoding/json" + "strconv" +) + +func NumberToInt(n json.Number) (int, error) { + n64, err := strconv.ParseInt(n.String(), 10, 32) + if nil != err { + return 0, err + } + return int(n64), nil +} diff --git a/reflect/convert.go b/reflect/convert.go new file mode 100644 index 0000000..3be00c6 --- /dev/null +++ b/reflect/convert.go @@ -0,0 +1,1153 @@ +package reflect + +import ( + "reflect" + "strconv" +) + +func ConvertToType(v interface{}, t reflect.Type) (interface{}, error) { + var ( + tt = reflect.TypeOf(v) + vv = reflect.ValueOf(v) + r interface{} + k int + err error + ) + + if t.Kind() == Interface { + return v, nil + } + + switch tt.Kind() { + case Slice: + switch t.Kind() { + case Slice: + var ( + res = reflect.MakeSlice( + t, + vv.Len(), + vv.Cap(), + ) + ) + + for k = 0; k < vv.Len(); k++ { + r, err = ConvertToType( + vv.Index(k).Interface(), + t.Elem(), + ) + if err != nil { + return nil, err + } + res.Index(k).Set(reflect.ValueOf(r)) + } + + return res.Interface(), nil + } + case Map: + switch t.Kind() { + case Map: + var ( + res = reflect.MakeMapWithSize(t, len(vv.MapKeys())) + ck interface{} + ) + for _, k := range vv.MapKeys() { + ck, err = ConvertToType( + k.Interface(), + t.Key(), + ) + if err != nil { + return nil, err + } + + r, err = ConvertToType( + vv.MapIndex(k).Interface(), + t.Elem(), + ) + if err != nil { + return nil, err + } + + res.SetMapIndex( + reflect.ValueOf(ck), + reflect.ValueOf(r), + ) + } + + return res.Interface(), nil + } + } + + switch t { + case TypeBool: + return ConvertToBool(v) + case TypeInt: + return ConvertToInt(v) + case TypeInt8: + return ConvertToInt8(v) + case TypeInt16: + return ConvertToInt16(v) + case TypeInt32: + return ConvertToInt32(v) + case TypeInt64: + return ConvertToInt64(v) + case TypeUint: + return ConvertToUint(v) + case TypeUint8: + return ConvertToUint8(v) + case TypeUint16: + return ConvertToUint16(v) + case TypeUint32: + return ConvertToUint32(v) + case TypeUint64: + return ConvertToUint64(v) + case TypeFloat32: + return ConvertToFloat32(v) + case TypeFloat64: + return ConvertToFloat64(v) + case TypeComplex64: + return ConvertToComplex64(v) + case TypeComplex128: + return ConvertToComplex128(v) + case TypeString: + return ConvertToString(v) + default: + return nil, NewErrCanNotConvertType( + v, + tt, + t, + ) + } +} + +func ConvertToBool(vv interface{}) (bool, error) { + var ( + v = Indirect(vv) + ) + + switch value := v.(type) { + case bool: + return value, nil + case nil: + return false, nil + case int: + if value != 0 { + return true, nil + } + return false, nil + case string: + if value == "" { + return false, nil + } + return strconv.ParseBool(value) + default: + return false, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeBool, + ) + } +} + +func ConvertToInt(vv interface{}) (int, error) { + var ( + v = Indirect(vv) + res int64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return value, nil + case int8: + return int(value), nil + case int16: + return int(value), nil + case int32: + return int(value), nil + case int64: + return int(value), nil + case uint: + return int(value), nil + case uint8: + return int(value), nil + case uint16: + return int(value), nil + case uint32: + return int(value), nil + case uint64: + return int(value), nil + case float32: + return int(value), nil + case float64: + return int(value), nil + case complex64: + return int(real(value)), nil + case complex128: + return int(real(value)), nil + case uintptr: + return int(value), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseInt(value, 0, 0) + if err == nil { + return int(res), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeInt, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeInt, + ) + } +} + +func ConvertToInt8(vv interface{}) (int8, error) { + var ( + v = Indirect(vv) + res int64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return int8(value), nil + case int8: + return value, nil + case int16: + return int8(value), nil + case int32: + return int8(value), nil + case int64: + return int8(value), nil + case uint: + return int8(value), nil + case uint8: + return int8(value), nil + case uint16: + return int8(value), nil + case uint32: + return int8(value), nil + case uint64: + return int8(value), nil + case float32: + return int8(value), nil + case float64: + return int8(value), nil + case complex64: + return int8(real(value)), nil + case complex128: + return int8(real(value)), nil + case uintptr: + return int8(value), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseInt(value, 0, 8) + if err == nil { + return int8(res), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeInt8, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeInt8, + ) + } +} + +func ConvertToInt16(vv interface{}) (int16, error) { + var ( + v = Indirect(vv) + res int64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return int16(value), nil + case int8: + return int16(value), nil + case int16: + return value, nil + case int32: + return int16(value), nil + case int64: + return int16(value), nil + case uint: + return int16(value), nil + case uint8: + return int16(value), nil + case uint16: + return int16(value), nil + case uint32: + return int16(value), nil + case uint64: + return int16(value), nil + case float32: + return int16(value), nil + case float64: + return int16(value), nil + case complex64: + return int16(real(value)), nil + case complex128: + return int16(real(value)), nil + case uintptr: + return int16(value), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseInt(value, 0, 16) + if err == nil { + return int16(res), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeInt16, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeInt16, + ) + } +} + +func ConvertToInt32(vv interface{}) (int32, error) { + var ( + v = Indirect(vv) + res int64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return int32(value), nil + case int8: + return int32(value), nil + case int16: + return int32(value), nil + case int32: + return value, nil + case int64: + return int32(value), nil + case uint: + return int32(value), nil + case uint8: + return int32(value), nil + case uint16: + return int32(value), nil + case uint32: + return int32(value), nil + case uint64: + return int32(value), nil + case float32: + return int32(value), nil + case float64: + return int32(value), nil + case complex64: + return int32(real(value)), nil + case complex128: + return int32(real(value)), nil + case uintptr: + return int32(value), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseInt(value, 0, 32) + if err == nil { + return int32(res), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeInt32, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeInt32, + ) + } +} + +func ConvertToInt64(vv interface{}) (int64, error) { + var ( + v = Indirect(vv) + res int64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return int64(value), nil + case int8: + return int64(value), nil + case int16: + return int64(value), nil + case int32: + return int64(value), nil + case int64: + return value, nil + case uint: + return int64(value), nil + case uint8: + return int64(value), nil + case uint16: + return int64(value), nil + case uint32: + return int64(value), nil + case uint64: + return int64(value), nil + case float32: + return int64(value), nil + case float64: + return int64(value), nil + case complex64: + return int64(real(value)), nil + case complex128: + return int64(real(value)), nil + case uintptr: + return int64(value), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseInt(value, 0, 64) + if err == nil { + return int64(res), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeInt64, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeInt64, + ) + } +} + +func ConvertToUint(vv interface{}) (uint, error) { + var ( + v = Indirect(vv) + res uint64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return uint(value), nil + case int8: + return uint(value), nil + case int16: + return uint(value), nil + case int32: + return uint(value), nil + case int64: + return uint(value), nil + case uint: + return value, nil + case uint8: + return uint(value), nil + case uint16: + return uint(value), nil + case uint32: + return uint(value), nil + case uint64: + return uint(value), nil + case float32: + return uint(value), nil + case float64: + return uint(value), nil + case complex64: + return uint(real(value)), nil + case complex128: + return uint(real(value)), nil + case uintptr: + return uint(value), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseUint(value, 0, 0) + if err == nil { + return uint(res), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeUint, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeUint, + ) + } +} + +func ConvertToUint8(vv interface{}) (uint8, error) { + var ( + v = Indirect(vv) + res uint64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return uint8(value), nil + case int8: + return uint8(value), nil + case int16: + return uint8(value), nil + case int32: + return uint8(value), nil + case int64: + return uint8(value), nil + case uint: + return uint8(value), nil + case uint8: + return value, nil + case uint16: + return uint8(value), nil + case uint32: + return uint8(value), nil + case uint64: + return uint8(value), nil + case float32: + return uint8(value), nil + case float64: + return uint8(value), nil + case complex64: + return uint8(real(value)), nil + case complex128: + return uint8(real(value)), nil + case uintptr: + return uint8(value), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseUint(value, 0, 8) + if err == nil { + return uint8(res), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeUint8, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeUint8, + ) + } +} + +func ConvertToUint16(vv interface{}) (uint16, error) { + var ( + v = Indirect(vv) + res uint64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return uint16(value), nil + case int8: + return uint16(value), nil + case int16: + return uint16(value), nil + case int32: + return uint16(value), nil + case int64: + return uint16(value), nil + case uint: + return uint16(value), nil + case uint8: + return uint16(value), nil + case uint16: + return value, nil + case uint32: + return uint16(value), nil + case uint64: + return uint16(value), nil + case float32: + return uint16(value), nil + case float64: + return uint16(value), nil + case complex64: + return uint16(real(value)), nil + case complex128: + return uint16(real(value)), nil + case uintptr: + return uint16(value), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseUint(value, 0, 16) + if err == nil { + return uint16(res), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeUint16, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeUint16, + ) + } + +} + +func ConvertToUint32(vv interface{}) (uint32, error) { + var ( + v = Indirect(vv) + res uint64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return uint32(value), nil + case int8: + return uint32(value), nil + case int16: + return uint32(value), nil + case int32: + return uint32(value), nil + case int64: + return uint32(value), nil + case uint: + return uint32(value), nil + case uint8: + return uint32(value), nil + case uint16: + return uint32(value), nil + case uint32: + return value, nil + case uint64: + return uint32(value), nil + case float32: + return uint32(value), nil + case float64: + return uint32(value), nil + case complex64: + return uint32(real(value)), nil + case complex128: + return uint32(real(value)), nil + case uintptr: + return uint32(value), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseUint(value, 0, 32) + if err == nil { + return uint32(res), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeUint32, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeUint32, + ) + } +} + +func ConvertToUint64(vv interface{}) (uint64, error) { + var ( + v = Indirect(vv) + res uint64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return uint64(value), nil + case int8: + return uint64(value), nil + case int16: + return uint64(value), nil + case int32: + return uint64(value), nil + case int64: + return uint64(value), nil + case uint: + return uint64(value), nil + case uint8: + return uint64(value), nil + case uint16: + return uint64(value), nil + case uint32: + return uint64(value), nil + case uint64: + return value, nil + case float32: + return uint64(value), nil + case float64: + return uint64(value), nil + case complex64: + return uint64(real(value)), nil + case complex128: + return uint64(real(value)), nil + case uintptr: + return uint64(value), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseUint(value, 0, 64) + if err == nil { + return uint64(res), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeUint64, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeUint64, + ) + } +} + +func ConvertToFloat32(vv interface{}) (float32, error) { + var ( + v = Indirect(vv) + res float64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return float32(value), nil + case int8: + return float32(value), nil + case int16: + return float32(value), nil + case int32: + return float32(value), nil + case int64: + return float32(value), nil + case uint: + return float32(value), nil + case uint8: + return float32(value), nil + case uint16: + return float32(value), nil + case uint32: + return float32(value), nil + case uint64: + return float32(value), nil + case float32: + return value, nil + case float64: + return float32(value), nil + case complex64: + return float32(real(value)), nil + case complex128: + return float32(real(value)), nil + case uintptr: + return float32(value), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseFloat(value, 32) + if err == nil { + return float32(res), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeFloat32, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeFloat32, + ) + } +} + +func ConvertToFloat64(vv interface{}) (float64, error) { + var ( + v = Indirect(vv) + res float64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return float64(value), nil + case int8: + return float64(value), nil + case int16: + return float64(value), nil + case int32: + return float64(value), nil + case int64: + return float64(value), nil + case uint: + return float64(value), nil + case uint8: + return float64(value), nil + case uint16: + return float64(value), nil + case uint32: + return float64(value), nil + case uint64: + return float64(value), nil + case float32: + return float64(value), nil + case float64: + return value, nil + case complex64: + return float64(real(value)), nil + case complex128: + return float64(real(value)), nil + case uintptr: + return float64(value), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseFloat(value, 32) + if err == nil { + return float64(res), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeFloat64, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeFloat64, + ) + } +} + +func ConvertToComplex64(vv interface{}) (complex64, error) { + var ( + v = Indirect(vv) + res float64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return complex64(complex(float32(value), 0)), nil + case int8: + return complex64(complex(float32(value), 0)), nil + case int16: + return complex64(complex(float32(value), 0)), nil + case int32: + return complex64(complex(float32(value), 0)), nil + case int64: + return complex64(complex(float32(value), 0)), nil + case uint: + return complex64(complex(float32(value), 0)), nil + case uint8: + return complex64(complex(float32(value), 0)), nil + case uint16: + return complex64(complex(float32(value), 0)), nil + case uint32: + return complex64(complex(float32(value), 0)), nil + case uint64: + return complex64(complex(float32(value), 0)), nil + case float32: + return complex64(complex(float32(value), 0)), nil + case float64: + return complex64(complex(float32(value), 0)), nil + case complex64: + return value, nil + case complex128: + return complex64(value), nil + case uintptr: + return complex64(complex(float32(value), 0)), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseFloat(value, 32) + if err == nil { + return complex64(complex(float32(res), 0)), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeComplex64, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeComplex64, + ) + } +} + +func ConvertToComplex128(vv interface{}) (complex128, error) { + var ( + v = Indirect(vv) + res float64 + err error + ) + + switch value := v.(type) { + case bool: + if value { + return 1, nil + } + return 0, nil + case int: + return complex128(complex(float32(value), 0)), nil + case int8: + return complex128(complex(float32(value), 0)), nil + case int16: + return complex128(complex(float32(value), 0)), nil + case int32: + return complex128(complex(float32(value), 0)), nil + case int64: + return complex128(complex(float32(value), 0)), nil + case uint: + return complex128(complex(float32(value), 0)), nil + case uint8: + return complex128(complex(float32(value), 0)), nil + case uint16: + return complex128(complex(float32(value), 0)), nil + case uint32: + return complex128(complex(float32(value), 0)), nil + case uint64: + return complex128(complex(float32(value), 0)), nil + case float32: + return complex128(complex(float32(value), 0)), nil + case float64: + return complex128(complex(float32(value), 0)), nil + case complex64: + return complex128(value), nil + case complex128: + return value, nil + case uintptr: + return complex128(complex(float32(value), 0)), nil + case string: + if value == "" { + return 0, nil + } + res, err = strconv.ParseFloat(value, 32) + if err == nil { + return complex128(complex(float32(res), 0)), nil + } + return 0, NewErrCanNotConvertType( + v, + reflect.TypeOf(vv), + TypeComplex128, + err.Error(), + ) + case nil: + return 0, nil + default: + return 0, NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeComplex128, + ) + } +} + +func ConvertToString(vv interface{}) (string, error) { + var ( + v = Indirect(vv) + ) + + switch value := v.(type) { + case bool: + return strconv.FormatBool(value), nil + case int: + return strconv.FormatInt(int64(value), 10), nil + case int8: + return strconv.FormatInt(int64(value), 10), nil + case int16: + return strconv.FormatInt(int64(value), 10), nil + case int32: + return strconv.FormatInt(int64(value), 10), nil + case int64: + return strconv.FormatInt(value, 0), nil + case uint: + return strconv.FormatInt(int64(value), 10), nil + case uint8: + return strconv.FormatInt(int64(value), 10), nil + case uint16: + return strconv.FormatInt(int64(value), 10), nil + case uint32: + return strconv.FormatInt(int64(value), 10), nil + case uint64: + return strconv.FormatInt(int64(value), 10), nil + case float32: + return strconv.FormatFloat(float64(value), 'f', -1, 32), nil + case float64: + return strconv.FormatFloat(value, 'f', -1, 64), nil + case complex64: + return strconv.FormatFloat(float64(real(value)), 'f', -1, 32), nil + case complex128: + return strconv.FormatFloat(real(value), 'f', -1, 64), nil + case uintptr: + return strconv.FormatInt(int64(value), 10), nil + case string: + return value, nil + case nil: + return "", nil + default: + return "", NewErrCanNotConvertType( + vv, + reflect.TypeOf(vv), + TypeString, + ) + } +} diff --git a/reflect/error.go b/reflect/error.go new file mode 100644 index 0000000..117d18a --- /dev/null +++ b/reflect/error.go @@ -0,0 +1,41 @@ +package reflect + +import ( + "fmt" + "reflect" + "strings" +) + +type ErrCanNotConvertType struct { + value interface{} + from reflect.Type + to reflect.Type + reason []string +} + +func (e ErrCanNotConvertType) Error() string { + var ( + reason = strings.Join(e.reason, ", ") + ) + + if reason != "" { + reason = ", reason: " + reason + } + + return fmt.Sprintf( + "Can not convert '%#v' of type '%s' to '%s'%s", + e.value, + e.from, + e.to, + reason, + ) +} + +func NewErrCanNotConvertType(value interface{}, from reflect.Type, to reflect.Type, reason ...string) ErrCanNotConvertType { + return ErrCanNotConvertType{ + value: value, + from: from, + to: to, + reason: reason, + } +} diff --git a/reflect/indirect.go b/reflect/indirect.go new file mode 100644 index 0000000..8156141 --- /dev/null +++ b/reflect/indirect.go @@ -0,0 +1,31 @@ +package reflect + +import ( + "reflect" +) + +func Indirect(v interface{}) interface{} { + if v == nil { + return nil + } + + return IndirectValue(reflect.ValueOf(v)).Interface() +} + +func IndirectValue(reflectValue reflect.Value) reflect.Value { + if reflectValue.Kind() == reflect.Ptr { + return reflectValue.Elem() + } + return reflectValue +} + +func IndirectType(reflectType reflect.Type) reflect.Type { + if reflectType == TypeInvalid { + return TypeInvalid + } + + if reflectType.Kind() == reflect.Ptr { + return reflectType.Elem() + } + return reflectType +} diff --git a/reflect/kind.go b/reflect/kind.go new file mode 100644 index 0000000..8ce5eef --- /dev/null +++ b/reflect/kind.go @@ -0,0 +1,35 @@ +package reflect + +import ( + "reflect" +) + +const ( + Invalid = reflect.Invalid + Bool = reflect.Bool + Int = reflect.Int + Int8 = reflect.Int8 + Int16 = reflect.Int16 + Int32 = reflect.Int32 + Int64 = reflect.Int64 + Uint = reflect.Uint + Uint8 = reflect.Uint8 + Uint16 = reflect.Uint16 + Uint32 = reflect.Uint32 + Uint64 = reflect.Uint64 + Uintptr = reflect.Uintptr + Float32 = reflect.Float32 + Float64 = reflect.Float64 + Complex64 = reflect.Complex64 + Complex128 = reflect.Complex128 + Array = reflect.Array + Chan = reflect.Chan + Func = reflect.Func + Interface = reflect.Interface + Map = reflect.Map + Ptr = reflect.Ptr + Slice = reflect.Slice + String = reflect.String + Struct = reflect.Struct + UnsafePointer = reflect.UnsafePointer +) diff --git a/reflect/type.go b/reflect/type.go new file mode 100644 index 0000000..1e070c9 --- /dev/null +++ b/reflect/type.go @@ -0,0 +1,72 @@ +package reflect + +import ( + "reflect" +) + +var ( + TypeOf = reflect.TypeOf +) + +var ( + Types = []reflect.Type{ + TypeBool, + TypeInt, + TypeInt8, + TypeInt16, + TypeInt32, + TypeInt64, + TypeUint, + TypeUint8, + TypeUint16, + TypeUint32, + TypeUint64, + TypeFloat32, + TypeFloat64, + TypeComplex64, + TypeComplex128, + TypeUintptr, + TypeString, + } + + TypeInvalid = reflect.Type(nil) + TypeBool = reflect.TypeOf(false) + TypeInt = reflect.TypeOf(int(0)) + TypeInt8 = reflect.TypeOf(int8(0)) + TypeInt16 = reflect.TypeOf(int16(0)) + TypeInt32 = reflect.TypeOf(int32(0)) + TypeInt64 = reflect.TypeOf(int64(0)) + TypeUint = reflect.TypeOf(uint(0)) + TypeUint8 = reflect.TypeOf(uint8(0)) + TypeUint16 = reflect.TypeOf(uint16(0)) + TypeUint32 = reflect.TypeOf(uint32(0)) + TypeUint64 = reflect.TypeOf(uint64(0)) + TypeFloat32 = reflect.TypeOf(float32(0)) + TypeFloat64 = reflect.TypeOf(float64(0)) + TypeComplex64 = reflect.TypeOf(complex64(0)) + TypeComplex128 = reflect.TypeOf(complex128(0)) + TypeUintptr = reflect.TypeOf(uintptr(0)) + TypeString = reflect.TypeOf(string("")) +) + +func IsTypeKind(t reflect.Type, kind reflect.Kind, removePtr bool) bool { + if reflect.Ptr == t.Kind() { + if removePtr { + return IsTypeKind(t.Elem(), kind, removePtr) + } + } + + return kind == t.Kind() +} + +func GetTypeInfo(t reflect.Type) (realType reflect.Type, pkgName string, name string) { + if reflect.Ptr == t.Kind() { + return GetTypeInfo(t.Elem()) + } + + return t, t.PkgPath(), t.Name() +} + +func ConvertStringToType() { + +}