package convert import ( "errors" "fmt" "reflect" "strconv" ) var ( ErrUnsupported = errors.New("unsupported") ) func isBytes(v reflect.Value) bool { if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 { return true } return false } func StringValue(v interface{}) (s string, err error) { if v == nil { return } refValue := reflect.Indirect(reflect.ValueOf(v)) switch refValue.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: s = strconv.FormatInt(refValue.Int(), 10) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: s = strconv.FormatUint(refValue.Uint(), 10) case reflect.Float32, reflect.Float64: s = strconv.FormatFloat(refValue.Float(), 'f', -1, 64) default: if isBytes(refValue) { s = string(refValue.Bytes()) } else { s = fmt.Sprint(refValue.Interface()) } } return } func IntegerValue(v interface{}) (n int64, err error) { if v == nil { return } refValue := reflect.Indirect(reflect.ValueOf(v)) switch refValue.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: n = refValue.Int() case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: n = int64(refValue.Uint()) case reflect.Float32, reflect.Float64: n = int64(refValue.Float()) case reflect.String: n, err = strconv.ParseInt(refValue.String(), 10, 64) default: if isBytes(refValue) { n, err = strconv.ParseInt(string(refValue.Bytes()), 10, 64) } else { err = ErrUnsupported } } return } func FloatValue(v interface{}) (n float64, err error) { if v == nil { return } refValue := reflect.Indirect(reflect.ValueOf(v)) switch refValue.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: n = float64(refValue.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: n = float64(refValue.Uint()) case reflect.Float32, reflect.Float64: n = refValue.Float() case reflect.String: n, err = strconv.ParseFloat(refValue.String(), 64) default: if isBytes(refValue) { n, err = strconv.ParseFloat(string(refValue.Bytes()), 64) } else { err = ErrUnsupported } } return } func MustString(v interface{}) (s string) { s, _ = StringValue(v) return } func MustInteger(v interface{}) (n int64) { n, _ = IntegerValue(v) return } func MustFloat(v interface{}) (n float64) { n, _ = FloatValue(v) return }