github.com/zhongdalu/gf@v1.0.0/g/util/gconv/gconv.go (about)

     1  // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/zhongdalu/gf.
     6  
     7  // Package gconv implements powerful and easy-to-use converting functionality for any types of variables.
     8  package gconv
     9  
    10  import (
    11  	"encoding/json"
    12  	"fmt"
    13  	"reflect"
    14  	"strconv"
    15  
    16  	"github.com/zhongdalu/gf/g/encoding/gbinary"
    17  )
    18  
    19  // Type assert api for String().
    20  type apiString interface {
    21  	String() string
    22  }
    23  
    24  // Type assert api for Error().
    25  type apiError interface {
    26  	Error() string
    27  }
    28  
    29  const (
    30  	gGCONV_TAG = "gconv"
    31  )
    32  
    33  var (
    34  	// Empty strings.
    35  	emptyStringMap = map[string]struct{}{
    36  		"":      struct{}{},
    37  		"0":     struct{}{},
    38  		"off":   struct{}{},
    39  		"false": struct{}{},
    40  	}
    41  
    42  	// Priority tags for Map*/Struct* functions.
    43  	structTagPriority = []string{gGCONV_TAG, "c", "json"}
    44  )
    45  
    46  // Convert converts the variable <i> to the type <t>, the type <t> is specified by string.
    47  // The unnecessary parameter <params> is used for additional parameter passing.
    48  func Convert(i interface{}, t string, params ...interface{}) interface{} {
    49  	switch t {
    50  	case "int":
    51  		return Int(i)
    52  	case "int8":
    53  		return Int8(i)
    54  	case "int16":
    55  		return Int16(i)
    56  	case "int32":
    57  		return Int32(i)
    58  	case "int64":
    59  		return Int64(i)
    60  	case "uint":
    61  		return Uint(i)
    62  	case "uint8":
    63  		return Uint8(i)
    64  	case "uint16":
    65  		return Uint16(i)
    66  	case "uint32":
    67  		return Uint32(i)
    68  	case "uint64":
    69  		return Uint64(i)
    70  	case "float32":
    71  		return Float32(i)
    72  	case "float64":
    73  		return Float64(i)
    74  	case "bool":
    75  		return Bool(i)
    76  	case "string":
    77  		return String(i)
    78  	case "[]byte":
    79  		return Bytes(i)
    80  	case "[]int":
    81  		return Ints(i)
    82  	case "[]string":
    83  		return Strings(i)
    84  
    85  	case "Time", "time.Time":
    86  		if len(params) > 0 {
    87  			return Time(i, String(params[0]))
    88  		}
    89  		return Time(i)
    90  
    91  	case "gtime.Time":
    92  		if len(params) > 0 {
    93  			return GTime(i, String(params[0]))
    94  		}
    95  		return *GTime(i)
    96  
    97  	case "GTime", "*gtime.Time":
    98  		if len(params) > 0 {
    99  			return GTime(i, String(params[0]))
   100  		}
   101  		return GTime(i)
   102  
   103  	case "Duration", "time.Duration":
   104  		return Duration(i)
   105  	default:
   106  		return i
   107  	}
   108  }
   109  
   110  // Byte converts <i> to byte.
   111  func Byte(i interface{}) byte {
   112  	if v, ok := i.(byte); ok {
   113  		return v
   114  	}
   115  	return byte(Uint8(i))
   116  }
   117  
   118  // Bytes converts <i> to []byte.
   119  func Bytes(i interface{}) []byte {
   120  	if i == nil {
   121  		return nil
   122  	}
   123  	switch value := i.(type) {
   124  	case string:
   125  		return []byte(value)
   126  	case []byte:
   127  		return value
   128  	default:
   129  		return gbinary.Encode(i)
   130  	}
   131  }
   132  
   133  // Rune converts <i> to rune.
   134  func Rune(i interface{}) rune {
   135  	if v, ok := i.(rune); ok {
   136  		return v
   137  	}
   138  	return rune(Int32(i))
   139  }
   140  
   141  // Runes converts <i> to []rune.
   142  func Runes(i interface{}) []rune {
   143  	if v, ok := i.([]rune); ok {
   144  		return v
   145  	}
   146  	return []rune(String(i))
   147  }
   148  
   149  // String converts <i> to string.
   150  func String(i interface{}) string {
   151  	if i == nil {
   152  		return ""
   153  	}
   154  	switch value := i.(type) {
   155  	case int:
   156  		return strconv.FormatInt(int64(value), 10)
   157  	case int8:
   158  		return strconv.Itoa(int(value))
   159  	case int16:
   160  		return strconv.Itoa(int(value))
   161  	case int32:
   162  		return strconv.Itoa(int(value))
   163  	case int64:
   164  		return strconv.FormatInt(int64(value), 10)
   165  	case uint:
   166  		return strconv.FormatUint(uint64(value), 10)
   167  	case uint8:
   168  		return strconv.FormatUint(uint64(value), 10)
   169  	case uint16:
   170  		return strconv.FormatUint(uint64(value), 10)
   171  	case uint32:
   172  		return strconv.FormatUint(uint64(value), 10)
   173  	case uint64:
   174  		return strconv.FormatUint(uint64(value), 10)
   175  	case float32:
   176  		return strconv.FormatFloat(float64(value), 'f', -1, 32)
   177  	case float64:
   178  		return strconv.FormatFloat(value, 'f', -1, 64)
   179  	case bool:
   180  		return strconv.FormatBool(value)
   181  	case string:
   182  		return value
   183  	case []byte:
   184  		return string(value)
   185  	case []rune:
   186  		return string(value)
   187  	default:
   188  		if f, ok := value.(apiString); ok {
   189  			// If the variable implements the String() interface,
   190  			// then use that interface to perform the conversion
   191  			return f.String()
   192  		} else if f, ok := value.(apiError); ok {
   193  			// If the variable implements the Error() interface,
   194  			// then use that interface to perform the conversion
   195  			return f.Error()
   196  		} else {
   197  			// Finally we use json.Marshal to convert.
   198  			if jsonContent, err := json.Marshal(value); err != nil {
   199  				return fmt.Sprint(value)
   200  			} else {
   201  				return string(jsonContent)
   202  			}
   203  		}
   204  	}
   205  }
   206  
   207  // Bool converts <i> to bool.
   208  // It returns false if <i> is: false, "", 0, "false", "off", empty slice/map.
   209  func Bool(i interface{}) bool {
   210  	if i == nil {
   211  		return false
   212  	}
   213  	switch value := i.(type) {
   214  	case bool:
   215  		return value
   216  	case string:
   217  		if _, ok := emptyStringMap[value]; ok {
   218  			return false
   219  		}
   220  		return true
   221  	default:
   222  		rv := reflect.ValueOf(i)
   223  		switch rv.Kind() {
   224  		case reflect.Ptr:
   225  			return !rv.IsNil()
   226  		case reflect.Map:
   227  			fallthrough
   228  		case reflect.Array:
   229  			fallthrough
   230  		case reflect.Slice:
   231  			return rv.Len() != 0
   232  		case reflect.Struct:
   233  			return true
   234  		default:
   235  			s := String(i)
   236  			if _, ok := emptyStringMap[s]; ok {
   237  				return false
   238  			}
   239  			return true
   240  		}
   241  	}
   242  }
   243  
   244  // Int converts <i> to int.
   245  func Int(i interface{}) int {
   246  	if i == nil {
   247  		return 0
   248  	}
   249  	if v, ok := i.(int); ok {
   250  		return v
   251  	}
   252  	return int(Int64(i))
   253  }
   254  
   255  // Int8 converts <i> to int8.
   256  func Int8(i interface{}) int8 {
   257  	if i == nil {
   258  		return 0
   259  	}
   260  	if v, ok := i.(int8); ok {
   261  		return v
   262  	}
   263  	return int8(Int64(i))
   264  }
   265  
   266  // Int16 converts <i> to int16.
   267  func Int16(i interface{}) int16 {
   268  	if i == nil {
   269  		return 0
   270  	}
   271  	if v, ok := i.(int16); ok {
   272  		return v
   273  	}
   274  	return int16(Int64(i))
   275  }
   276  
   277  // Int32 converts <i> to int32.
   278  func Int32(i interface{}) int32 {
   279  	if i == nil {
   280  		return 0
   281  	}
   282  	if v, ok := i.(int32); ok {
   283  		return v
   284  	}
   285  	return int32(Int64(i))
   286  }
   287  
   288  // Int64 converts <i> to int64.
   289  func Int64(i interface{}) int64 {
   290  	if i == nil {
   291  		return 0
   292  	}
   293  	switch value := i.(type) {
   294  	case int:
   295  		return int64(value)
   296  	case int8:
   297  		return int64(value)
   298  	case int16:
   299  		return int64(value)
   300  	case int32:
   301  		return int64(value)
   302  	case int64:
   303  		return value
   304  	case uint:
   305  		return int64(value)
   306  	case uint8:
   307  		return int64(value)
   308  	case uint16:
   309  		return int64(value)
   310  	case uint32:
   311  		return int64(value)
   312  	case uint64:
   313  		return int64(value)
   314  	case float32:
   315  		return int64(value)
   316  	case float64:
   317  		return int64(value)
   318  	case bool:
   319  		if value {
   320  			return 1
   321  		}
   322  		return 0
   323  	case []byte:
   324  		return gbinary.DecodeToInt64(value)
   325  	default:
   326  		s := String(value)
   327  		// Hexadecimal
   328  		if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
   329  			if v, e := strconv.ParseInt(s[2:], 16, 64); e == nil {
   330  				return v
   331  			}
   332  		}
   333  		// Octal
   334  		if len(s) > 1 && s[0] == '0' {
   335  			if v, e := strconv.ParseInt(s[1:], 8, 64); e == nil {
   336  				return v
   337  			}
   338  		}
   339  		// Decimal
   340  		if v, e := strconv.ParseInt(s, 10, 64); e == nil {
   341  			return v
   342  		}
   343  		// Float64
   344  		return int64(Float64(value))
   345  	}
   346  }
   347  
   348  // Uint converts <i> to uint.
   349  func Uint(i interface{}) uint {
   350  	if i == nil {
   351  		return 0
   352  	}
   353  	if v, ok := i.(uint); ok {
   354  		return v
   355  	}
   356  	return uint(Uint64(i))
   357  }
   358  
   359  // Uint8 converts <i> to uint8.
   360  func Uint8(i interface{}) uint8 {
   361  	if i == nil {
   362  		return 0
   363  	}
   364  	if v, ok := i.(uint8); ok {
   365  		return v
   366  	}
   367  	return uint8(Uint64(i))
   368  }
   369  
   370  // Uint16 converts <i> to uint16.
   371  func Uint16(i interface{}) uint16 {
   372  	if i == nil {
   373  		return 0
   374  	}
   375  	if v, ok := i.(uint16); ok {
   376  		return v
   377  	}
   378  	return uint16(Uint64(i))
   379  }
   380  
   381  // Uint32 converts <i> to uint32.
   382  func Uint32(i interface{}) uint32 {
   383  	if i == nil {
   384  		return 0
   385  	}
   386  	if v, ok := i.(uint32); ok {
   387  		return v
   388  	}
   389  	return uint32(Uint64(i))
   390  }
   391  
   392  // Uint64 converts <i> to uint64.
   393  func Uint64(i interface{}) uint64 {
   394  	if i == nil {
   395  		return 0
   396  	}
   397  	switch value := i.(type) {
   398  	case int:
   399  		return uint64(value)
   400  	case int8:
   401  		return uint64(value)
   402  	case int16:
   403  		return uint64(value)
   404  	case int32:
   405  		return uint64(value)
   406  	case int64:
   407  		return uint64(value)
   408  	case uint:
   409  		return uint64(value)
   410  	case uint8:
   411  		return uint64(value)
   412  	case uint16:
   413  		return uint64(value)
   414  	case uint32:
   415  		return uint64(value)
   416  	case uint64:
   417  		return value
   418  	case float32:
   419  		return uint64(value)
   420  	case float64:
   421  		return uint64(value)
   422  	case bool:
   423  		if value {
   424  			return 1
   425  		}
   426  		return 0
   427  	case []byte:
   428  		return gbinary.DecodeToUint64(value)
   429  	default:
   430  		s := String(value)
   431  		// Hexadecimal
   432  		if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
   433  			if v, e := strconv.ParseUint(s[2:], 16, 64); e == nil {
   434  				return v
   435  			}
   436  		}
   437  		// Octal
   438  		if len(s) > 1 && s[0] == '0' {
   439  			if v, e := strconv.ParseUint(s[1:], 8, 64); e == nil {
   440  				return v
   441  			}
   442  		}
   443  		// Decimal
   444  		if v, e := strconv.ParseUint(s, 10, 64); e == nil {
   445  			return v
   446  		}
   447  		// Float64
   448  		return uint64(Float64(value))
   449  	}
   450  }
   451  
   452  // Float32 converts <i> to float32.
   453  func Float32(i interface{}) float32 {
   454  	if i == nil {
   455  		return 0
   456  	}
   457  	switch value := i.(type) {
   458  	case float32:
   459  		return value
   460  	case float64:
   461  		return float32(value)
   462  	case []byte:
   463  		return gbinary.DecodeToFloat32(value)
   464  	default:
   465  		v, _ := strconv.ParseFloat(String(i), 64)
   466  		return float32(v)
   467  	}
   468  }
   469  
   470  // Float64 converts <i> to float64.
   471  func Float64(i interface{}) float64 {
   472  	if i == nil {
   473  		return 0
   474  	}
   475  	switch value := i.(type) {
   476  	case float32:
   477  		return float64(value)
   478  	case float64:
   479  		return value
   480  	case []byte:
   481  		return gbinary.DecodeToFloat64(value)
   482  	default:
   483  		v, _ := strconv.ParseFloat(String(i), 64)
   484  		return v
   485  	}
   486  }