Files
baseapi/utils/typeconv.go
2018-10-29 16:33:44 +08:00

334 lines
7.3 KiB
Go

package utils
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"reflect"
"strconv"
"strings"
"time"
"git.rosy.net.cn/baseapi"
)
var (
DefaultTimeValue = Str2Time("1970-01-01 00:00:00")
)
func GetConcretValue(value reflect.Value) reflect.Value {
for {
if value.Kind() == reflect.Interface || value.Kind() == reflect.Ptr {
value = value.Elem()
} else {
break
}
}
return value
}
func UnmarshalUseNumber(data []byte, result interface{}) error {
d := json.NewDecoder(bytes.NewReader(data))
d.UseNumber()
err := d.Decode(result)
if err != nil {
baseapi.SugarLogger.Errorf("decode data:%v, error:%v", string(data), err)
}
return err
}
func MustMarshal(obj interface{}) []byte {
byteArr, err := json.Marshal(obj)
if err != nil {
panic(fmt.Sprintf("err when Marshal obj:%v with error:%v", obj, err))
}
return byteArr
}
func MustInterface2Int64(data interface{}) int64 {
dataNumber, ok := data.(json.Number)
if !ok {
panic(fmt.Sprintf("error when cast:%v to int64", data))
}
retVal, err := dataNumber.Int64()
if err != nil {
panic(err.Error())
}
return retVal
}
func Interface2Int64WithDefault(data interface{}, defValue int64) int64 {
if data == nil {
return defValue
}
return MustInterface2Int64(data)
}
func Interface2DirectIntWithDefault(data interface{}, defValue int) int {
if data == nil {
return defValue
}
return data.(int)
}
func MustInterface2Float64(data interface{}) float64 {
dataNumber, ok := data.(json.Number)
if !ok {
panic(fmt.Sprintf("error when convert:%v", data))
}
retVal, err := dataNumber.Float64()
if err != nil {
panic(err.Error())
}
return retVal
}
func Interface2FloatWithDefault(data interface{}, defValue float64) (retVal float64) {
if data == nil {
return defValue
}
return MustInterface2Float64(data)
}
func Interface2String(data interface{}) string {
if data == nil {
return ""
}
return data.(string)
}
func Interface2Int64List(data interface{}) []int64 {
if data == nil {
return nil
}
list := data.([]interface{})
retVal := make([]int64, len(list))
for k, v := range list {
retVal[k] = MustInterface2Int64(v)
}
return retVal
}
func Interface2StringList(data interface{}) []string {
if data == nil {
return nil
}
list := data.([]interface{})
retVal := make([]string, len(list))
for k, v := range list {
retVal[k] = Interface2String(v)
}
return retVal
}
func Interface2Slice(value interface{}) (retVal []interface{}) {
typeInfo := reflect.TypeOf(value)
if typeInfo.Kind() != reflect.Slice {
panic("list must be slice type!")
}
if value != nil {
valueInfo := reflect.ValueOf(value)
retVal = make([]interface{}, valueInfo.Len())
for i := 0; i < valueInfo.Len(); i++ {
retVal[i] = valueInfo.Index(i).Interface()
}
}
return retVal
}
func Slice2MapSlice(data []interface{}) []map[string]interface{} {
retVal := make([]map[string]interface{}, len(data))
for k, v := range data {
retVal[k] = v.(map[string]interface{})
}
return retVal
}
//
func Bool2String(value bool) string {
if value {
return "true"
}
return "false"
}
func Str2Int64WithDefault(str string, defValue int64) int64 {
retVal, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return defValue
}
return retVal
}
func Str2Int64(str string) int64 {
retVal, err := strconv.ParseInt(str, 10, 64)
if err != nil {
baseapi.SugarLogger.Errorf("error when convert %s to int64", str)
}
return retVal
}
func Str2Float64WithDefault(str string, defValue float64) float64 {
retVal, err := strconv.ParseFloat(str, 64)
if err != nil {
retVal = defValue
}
return retVal
}
func Str2Float64(str string) float64 {
retVal, err := strconv.ParseFloat(str, 64)
if err != nil {
baseapi.SugarLogger.Errorf("error when convert %s to float64", str)
}
return retVal
}
func Int64ToStr(value int64) string {
return strconv.FormatInt(value, 10)
}
func Int2Str(value int) string {
return strconv.Itoa(value)
}
// timestamp is in second
func Timestamp2Str(timestamp int64) string {
return Time2Str(Timestamp2Time(timestamp))
}
func Timestamp2Time(timestamp int64) time.Time {
const normalTimestamp = 1533709322
if timestamp > normalTimestamp*100 { // 传成毫秒了
baseapi.SugarLogger.Errorf("Timestamp2Time wrong timestamp:%d", timestamp)
timestamp = timestamp / 1000
}
return time.Unix(timestamp, 0)
}
func Time2Str(t time.Time) string {
return t.Format("2006-01-02 15:04:05")
}
func Str2Time(timeStr string) time.Time {
timeStr = strings.Replace(timeStr, "T", " ", 1)
if strings.Index(timeStr, " ") == -1 {
timeStr += " 00:00:00"
}
retVal, err := time.ParseInLocation("2006-1-2 15:4:5", timeStr, time.Local)
if err != nil {
baseapi.SugarLogger.Errorf("time.ParseInLocation failed, timeStr:%v, error:%v", timeStr, err)
}
return retVal
}
func Str2TimeWithDefault(timeStr string, defValue time.Time) time.Time {
timeStr = strings.Replace(timeStr, "T", " ", 1)
retVal, err := time.ParseInLocation("2006-1-2 15:4:5", timeStr, time.Local)
if err != nil {
return defValue
}
return retVal
}
func HTTPResponse2Json(response *http.Response) (map[string]interface{}, error) {
var jsonResult map[string]interface{}
bodyData, err := ioutil.ReadAll(response.Body)
if err != nil {
baseapi.SugarLogger.Errorf("ioutil.ReadAll error:%v, response:%v", err, response)
return nil, err
}
if err = UnmarshalUseNumber(bodyData, &jsonResult); err != nil {
return nil, err
}
return jsonResult, nil
}
func HTTPBody2Values(data []byte, needDecode bool) (url.Values, error) {
bodyStr := string(data)
if needDecode {
bodyStr1, err := url.QueryUnescape(bodyStr)
if err != nil {
baseapi.SugarLogger.Errorf("QueryUnescape error:%v, bodyStr:%v", err, bodyStr)
return nil, err
}
bodyStr = bodyStr1
}
result, err := url.ParseQuery(bodyStr)
if err != nil {
baseapi.SugarLogger.Errorf("ParseQuery error:%v, bodyStr:%v", err, bodyStr)
return nil, err
}
return result, nil
}
func Params2Map(key1, value1 interface{}, kv ...interface{}) (retVal map[string]interface{}) {
retVal = make(map[string]interface{})
retVal[key1.(string)] = value1
key := ""
for index, v := range kv {
if index%2 == 0 {
key = v.(string)
} else {
retVal[key] = v
}
}
return retVal
}
func URLValues2Map(values url.Values) (retVal map[string]interface{}) {
retVal = make(map[string]interface{})
for k := range values {
retVal[k] = values.Get(k)
}
return retVal
}
func Map2URLValues(mapData map[string]interface{}) (retVal url.Values) {
retVal = make(url.Values)
for k, v := range mapData {
retVal.Set(k, fmt.Sprint(v))
}
return retVal
}
func MapKV2List(mapData map[string]interface{}) []map[string]interface{} {
retVal := make([]map[string]interface{}, len(mapData))
index := 0
for _, v := range mapData {
retVal[index] = v.(map[string]interface{})
index++
}
return retVal
}
func Format4Output(obj interface{}, isSingleLine bool) (retVal string) {
retVal, ok := obj.(string)
if !ok {
var (
result []byte
err error
)
if isSingleLine {
if result, err = json.Marshal(obj); err == nil {
retVal = string(result)
}
} else {
if result, err = json.MarshalIndent(obj, "", "\t"); err == nil {
retVal = string(result)
}
}
if err != nil {
baseapi.SugarLogger.Infof("Format4Output Marshal:%v failed with error:%v", obj, err)
retVal = fmt.Sprintf("%v", obj)
}
}
return retVal
}