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 }