github.com/codingeasygo/util@v0.0.0-20231206062002-1ce2f004b7d9/converter/converter.go (about) 1 package converter 2 3 import ( 4 "database/sql/driver" 5 "encoding/json" 6 "encoding/xml" 7 "fmt" 8 "io" 9 "io/ioutil" 10 "reflect" 11 "strconv" 12 "strings" 13 "time" 14 ) 15 16 var ErrNil = fmt.Errorf("nil value") 17 18 func valueConvert(v interface{}, targetType reflect.Type, defaultRet interface{}, parse func(string) (interface{}, error)) (result interface{}, err error) { 19 targetValue := reflect.ValueOf(v) 20 if !targetValue.IsValid() { 21 return defaultRet, ErrNil 22 } 23 if timeValue, ok := v.(time.Time); ok { 24 if targetValue.IsZero() { 25 targetValue = reflect.ValueOf(int64(0)) 26 } else { 27 targetValue = reflect.ValueOf(timeValue.Local().UnixNano() / 1e6) 28 } 29 } 30 if targetValue.CanConvert(reflect.TypeOf(time.Time{})) { 31 if targetValue.IsZero() { 32 targetValue = reflect.ValueOf(int64(0)) 33 } else { 34 targetValue = reflect.ValueOf(targetValue.Convert(reflect.TypeOf(time.Time{})).Interface().(time.Time).Local().UnixNano() / 1e6) 35 } 36 } 37 if targetValue.Kind() == reflect.String { 38 result, err = parse(targetValue.String()) 39 if err != nil { 40 return defaultRet, err 41 } 42 targetValue = reflect.ValueOf(result) 43 } 44 if targetValue.CanConvert(targetType) { 45 return targetValue.Convert(targetType).Interface(), nil 46 } 47 if targetValue.Kind() == reflect.Ptr { 48 targetValue = reflect.Indirect(targetValue) 49 if !targetValue.IsValid() { 50 return defaultRet, ErrNil 51 } 52 result, err = valueConvert(targetValue.Interface(), targetType, defaultRet, parse) 53 return 54 } 55 if valuer, ok := v.(driver.Valuer); ok { 56 driverValue, xerr := valuer.Value() 57 if xerr != nil { 58 err = xerr 59 return 60 } 61 result, err = valueConvert(driverValue, targetType, defaultRet, parse) 62 return 63 } 64 return defaultRet, fmt.Errorf("incompactable kind(%v)", targetValue.Kind()) 65 } 66 67 func Int(v interface{}) (val int) { 68 val, _ = IntVal(v) 69 return 70 } 71 72 var _intType = reflect.TypeOf(0) 73 74 func IntVal(v interface{}) (int, error) { 75 ret, err := valueConvert(v, _intType, 0, func(s string) (interface{}, error) { 76 return strconv.ParseInt(strings.TrimSpace(s), 10, 64) 77 }) 78 if err != nil { 79 return 0, err 80 } 81 return ret.(int), nil 82 } 83 84 func Int64(v interface{}) int64 { 85 val, _ := Int64Val(v) 86 return val 87 } 88 89 var _int64Type = reflect.TypeOf(int64(0)) 90 91 func Int64Val(v interface{}) (int64, error) { 92 ret, err := valueConvert(v, _int64Type, 0, func(s string) (interface{}, error) { 93 return strconv.ParseInt(strings.TrimSpace(s), 10, 64) 94 }) 95 if err != nil { 96 return 0, err 97 } 98 return ret.(int64), nil 99 } 100 101 func Uint64(v interface{}) uint64 { 102 val, _ := Uint64Val(v) 103 return val 104 } 105 106 var _uint64Type = reflect.TypeOf(uint64(0)) 107 108 func Uint64Val(v interface{}) (uint64, error) { 109 ret, err := valueConvert(v, _uint64Type, 0, func(s string) (interface{}, error) { 110 return strconv.ParseInt(strings.TrimSpace(s), 10, 64) 111 }) 112 if err != nil { 113 return 0, err 114 } 115 return ret.(uint64), nil 116 } 117 118 func Float64(v interface{}) float64 { 119 val, _ := Float64Val(v) 120 return val 121 } 122 123 var _float64Type = reflect.TypeOf(float64(0)) 124 125 func Float64Val(v interface{}) (float64, error) { 126 ret, err := valueConvert(v, _float64Type, 0, func(s string) (interface{}, error) { 127 return strconv.ParseFloat(strings.TrimSpace(s), 64) 128 }) 129 if err != nil { 130 return 0, err 131 } 132 return ret.(float64), nil 133 } 134 135 func String(v interface{}) string { 136 val, _ := StringVal(v) 137 return val 138 } 139 140 func StringVal(v interface{}) (res string, err error) { 141 if v == nil { 142 return "", ErrNil 143 } 144 switch v := v.(type) { 145 case string: 146 return v, nil 147 case *string: 148 return *v, nil 149 case []byte: 150 return string(v), nil 151 case *[]byte: 152 return string(*v), nil 153 default: 154 return fmt.Sprintf("%v", v), nil 155 } 156 } 157 158 //ArrayVal will convert value to array, if v is string will split it by comma, if v is slice will loop element to array, other will error 159 func ArrayVal(v interface{}) ([]interface{}, error) { 160 return ArrayValAll(v, false) 161 } 162 163 //ArrayValAll will convert all value to array, if v is string will split it by comma, if v is slice will loop element to array, other will return []interface{}{v} when all is true 164 func ArrayValAll(v interface{}, all bool) ([]interface{}, error) { 165 if v == nil { 166 return nil, ErrNil 167 } 168 if vals, ok := v.([]interface{}); ok { 169 return vals, nil 170 } 171 if sval, ok := v.(string); ok { 172 vals := []interface{}{} 173 for _, val := range strings.Split(sval, ",") { 174 vals = append(vals, val) 175 } 176 return vals, nil 177 } 178 if sval, ok := v.(*string); ok { 179 if sval == nil { 180 return nil, ErrNil 181 } 182 vals := []interface{}{} 183 for _, val := range strings.Split(*sval, ",") { 184 vals = append(vals, val) 185 } 186 return vals, nil 187 } 188 vals := reflect.ValueOf(v) 189 if vals.Kind() != reflect.Slice { 190 if all { 191 return []interface{}{v}, nil 192 } 193 return nil, fmt.Errorf("incompactable kind(%v)", vals.Kind()) 194 } 195 var vs = []interface{}{} 196 for i := 0; i < vals.Len(); i++ { 197 vs = append(vs, vals.Index(i).Interface()) 198 } 199 return vs, nil 200 } 201 202 func ArrayStringVal(v interface{}) (svals []string, err error) { 203 if v == nil { 204 return nil, ErrNil 205 } 206 var sval string 207 if vals, ok := v.([]interface{}); ok { 208 for _, v := range vals { 209 sval, err = StringVal(v) 210 if err != nil { 211 return 212 } 213 svals = append(svals, sval) 214 } 215 return 216 } 217 if sval, ok := v.(string); ok { 218 svals = strings.Split(sval, ",") 219 return 220 } 221 if sval, ok := v.(*string); ok { 222 if sval == nil { 223 return nil, ErrNil 224 } 225 svals = strings.Split(*sval, ",") 226 return 227 } 228 vals := reflect.ValueOf(v) 229 if vals.Kind() != reflect.Slice { 230 err = fmt.Errorf("incompactable kind(%v)", vals.Kind()) 231 return 232 } 233 for i := 0; i < vals.Len(); i++ { 234 if vals.Index(i).IsZero() { 235 sval, err = StringVal(nil) 236 } else { 237 sval, err = StringVal(vals.Index(i).Interface()) 238 } 239 if err != nil { 240 return 241 } 242 svals = append(svals, sval) 243 } 244 return 245 } 246 247 func ArrayIntVal(v interface{}) (ivals []int, err error) { 248 if v == nil { 249 return nil, ErrNil 250 } 251 var ival int 252 if vals, ok := v.([]interface{}); ok { 253 for _, v := range vals { 254 ival, err = IntVal(v) 255 if err != nil { 256 return 257 } 258 ivals = append(ivals, ival) 259 } 260 return 261 } 262 if sval, ok := v.(string); ok { 263 for _, val := range strings.Split(sval, ",") { 264 ival, err = IntVal(val) 265 if err != nil { 266 return 267 } 268 ivals = append(ivals, ival) 269 } 270 return 271 } 272 if sval, ok := v.(*string); ok { 273 if sval == nil { 274 return nil, ErrNil 275 } 276 for _, val := range strings.Split(*sval, ",") { 277 ival, err = IntVal(val) 278 if err != nil { 279 return 280 } 281 ivals = append(ivals, ival) 282 } 283 return 284 } 285 vals := reflect.ValueOf(v) 286 if vals.Kind() != reflect.Slice { 287 err = fmt.Errorf("incompactable kind(%v)", vals.Kind()) 288 return 289 } 290 for i := 0; i < vals.Len(); i++ { 291 ival, err = IntVal(vals.Index(i).Interface()) 292 if err != nil { 293 return 294 } 295 ivals = append(ivals, ival) 296 } 297 return 298 } 299 300 func ArrayInt64Val(v interface{}) (ivals []int64, err error) { 301 if v == nil { 302 return nil, ErrNil 303 } 304 var ival int64 305 if vals, ok := v.([]interface{}); ok { 306 for _, v := range vals { 307 ival, err = Int64Val(v) 308 if err != nil { 309 return 310 } 311 ivals = append(ivals, ival) 312 } 313 return 314 } 315 if sval, ok := v.(string); ok { 316 for _, val := range strings.Split(sval, ",") { 317 ival, err = Int64Val(val) 318 if err != nil { 319 return 320 } 321 ivals = append(ivals, ival) 322 } 323 return 324 } 325 if sval, ok := v.(*string); ok { 326 if sval == nil { 327 return nil, ErrNil 328 } 329 for _, val := range strings.Split(*sval, ",") { 330 ival, err = Int64Val(val) 331 if err != nil { 332 return 333 } 334 ivals = append(ivals, ival) 335 } 336 return 337 } 338 vals := reflect.ValueOf(v) 339 if vals.Kind() != reflect.Slice { 340 err = fmt.Errorf("incompactable kind(%v)", vals.Kind()) 341 return 342 } 343 for i := 0; i < vals.Len(); i++ { 344 ival, err = Int64Val(vals.Index(i).Interface()) 345 if err != nil { 346 return 347 } 348 ivals = append(ivals, ival) 349 } 350 return 351 } 352 353 func ArrayUint64Val(v interface{}) (ivals []uint64, err error) { 354 if v == nil { 355 return nil, ErrNil 356 } 357 var ival uint64 358 if vals, ok := v.([]interface{}); ok { 359 for _, v := range vals { 360 ival, err = Uint64Val(v) 361 if err != nil { 362 return 363 } 364 ivals = append(ivals, ival) 365 } 366 return 367 } 368 if sval, ok := v.(string); ok { 369 for _, val := range strings.Split(sval, ",") { 370 ival, err = Uint64Val(val) 371 if err != nil { 372 return 373 } 374 ivals = append(ivals, ival) 375 } 376 return 377 } 378 if sval, ok := v.(*string); ok { 379 if sval == nil { 380 return nil, ErrNil 381 } 382 for _, val := range strings.Split(*sval, ",") { 383 ival, err = Uint64Val(val) 384 if err != nil { 385 return 386 } 387 ivals = append(ivals, ival) 388 } 389 return 390 } 391 vals := reflect.ValueOf(v) 392 if vals.Kind() != reflect.Slice { 393 err = fmt.Errorf("incompactable kind(%v)", vals.Kind()) 394 return 395 } 396 for i := 0; i < vals.Len(); i++ { 397 ival, err = Uint64Val(vals.Index(i).Interface()) 398 if err != nil { 399 return 400 } 401 ivals = append(ivals, ival) 402 } 403 return 404 } 405 406 func ArrayFloat64Val(v interface{}) (ivals []float64, err error) { 407 if v == nil { 408 return nil, ErrNil 409 } 410 var ival float64 411 if vals, ok := v.([]interface{}); ok { 412 for _, v := range vals { 413 ival, err = Float64Val(v) 414 if err != nil { 415 return 416 } 417 ivals = append(ivals, ival) 418 } 419 return 420 } 421 if sval, ok := v.(string); ok { 422 for _, val := range strings.Split(sval, ",") { 423 ival, err = Float64Val(val) 424 if err != nil { 425 return 426 } 427 ivals = append(ivals, ival) 428 } 429 return 430 } 431 if sval, ok := v.(*string); ok { 432 if sval == nil { 433 return nil, ErrNil 434 } 435 for _, val := range strings.Split(*sval, ",") { 436 ival, err = Float64Val(val) 437 if err != nil { 438 return 439 } 440 ivals = append(ivals, ival) 441 } 442 return 443 } 444 vals := reflect.ValueOf(v) 445 if vals.Kind() != reflect.Slice { 446 err = fmt.Errorf("incompactable kind(%v)", vals.Kind()) 447 return 448 } 449 for i := 0; i < vals.Len(); i++ { 450 ival, err = Float64Val(vals.Index(i).Interface()) 451 if err != nil { 452 return 453 } 454 ivals = append(ivals, ival) 455 } 456 return 457 } 458 459 //ArrayHaving will return true if the array element having one is in objs 460 func ArrayHaving(ary interface{}, objs ...interface{}) bool { 461 switch reflect.TypeOf(ary).Kind() { 462 case reflect.Slice: 463 s := reflect.ValueOf(ary) 464 for i := 0; i < s.Len(); i++ { 465 for _, obj := range objs { 466 if obj == s.Index(i).Interface() { 467 return true 468 } 469 } 470 } 471 return false 472 default: 473 return false 474 } 475 } 476 477 func JSON(v interface{}) string { 478 data, err := json.Marshal(v) 479 if err != nil { 480 return err.Error() 481 } 482 return string(data) 483 } 484 485 func XML(v interface{}) string { 486 data, err := xml.Marshal(v) 487 if err != nil { 488 return err.Error() 489 } 490 return string(data) 491 } 492 493 //UnmarshalJSON will read bytes from reader and unmarshal to object 494 func UnmarshalJSON(r io.Reader, v interface{}) (data []byte, err error) { 495 data, err = ioutil.ReadAll(r) 496 if err == nil || err == io.EOF { 497 err = json.Unmarshal(data, v) 498 } 499 return 500 } 501 502 //UnmarshalXML will read bytes from reader and unmarshal to object 503 func UnmarshalXML(r io.Reader, v interface{}) (data []byte, err error) { 504 data, err = ioutil.ReadAll(r) 505 if err == nil || err == io.EOF { 506 err = xml.Unmarshal(data, v) 507 } 508 return 509 } 510 511 // Int8Ptr - 512 func Int8Ptr(arg int8) *int8 { 513 return &arg 514 } 515 516 // Uint8Ptr - 517 func Uint8Ptr(arg uint8) *uint8 { 518 return &arg 519 } 520 521 // Int16Ptr - 522 func Int16Ptr(arg int16) *int16 { 523 return &arg 524 } 525 526 // Uint16Ptr - 527 func Uint16Ptr(arg uint16) *uint16 { 528 return &arg 529 } 530 531 // IntPtr - 532 func IntPtr(arg int) *int { 533 return &arg 534 } 535 536 // UintPtr - 537 func UintPtr(arg uint) *uint { 538 return &arg 539 } 540 541 // Int32Ptr - 542 func Int32Ptr(arg int32) *int32 { 543 return &arg 544 } 545 546 // Uint32Ptr - 547 func Uint32Ptr(arg uint32) *uint32 { 548 return &arg 549 } 550 551 // Int64Ptr - 552 func Int64Ptr(arg int64) *int64 { 553 return &arg 554 } 555 556 // Uint64Ptr - 557 func Uint64Ptr(arg uint64) *uint64 { 558 return &arg 559 } 560 561 // Float32Ptr - 562 func Float32Ptr(arg float32) *float32 { 563 return &arg 564 } 565 566 // Float64Ptr - 567 func Float64Ptr(arg float64) *float64 { 568 return &arg 569 } 570 571 // StringPtr - 572 func StringPtr(arg string) *string { 573 return &arg 574 } 575 576 //Join all slice to string 577 func Join(v interface{}, sep string) string { 578 vtype := reflect.TypeOf(v) 579 if vtype.Kind() != reflect.Slice { 580 panic("not slice") 581 } 582 vval := reflect.ValueOf(v) 583 if vval.Len() < 1 { 584 return "" 585 } 586 val := fmt.Sprintf("%v", reflect.Indirect(vval.Index(0)).Interface()) 587 for i := 1; i < vval.Len(); i++ { 588 val += fmt.Sprintf("%v%v", sep, reflect.Indirect(vval.Index(i)).Interface()) 589 } 590 return val 591 } 592 593 const ( 594 JoinPolicyNotSliceEmpty = 1 << 0 595 JoinPolicyNotSliceString = 1 << 1 596 JoinPolicyNilSkip = 1 << 5 597 JoinPolicyNilString = 1 << 6 598 JoinPolicyDefault = JoinPolicyNotSliceEmpty | JoinPolicyNilSkip 599 ) 600 601 func JoinSafe(v interface{}, sep string, policy int) string { 602 vtype := reflect.TypeOf(v) 603 if vtype.Kind() != reflect.Slice { 604 if policy&JoinPolicyNotSliceString == JoinPolicyNotSliceString { 605 return fmt.Sprintf("%v", v) 606 } else { 607 return "" 608 } 609 } 610 vval := reflect.ValueOf(v) 611 if vval.Len() < 1 { 612 return "" 613 } 614 stringVal := func(v reflect.Value) (string, bool) { 615 if v.Kind() == reflect.Ptr && v.IsNil() { 616 if policy&JoinPolicyNilString == JoinPolicyNilString { 617 return fmt.Sprintf("%v", v), true 618 } else { 619 return "", false 620 } 621 } 622 v = reflect.Indirect(v) 623 return fmt.Sprintf("%v", v.Interface()), true 624 } 625 val := "" 626 for i := 0; i < vval.Len(); i++ { 627 s, ok := stringVal(vval.Index(i)) 628 if !ok { 629 continue 630 } 631 if len(val) > 0 { 632 val += fmt.Sprintf("%v%v", sep, s) 633 } else { 634 val = s 635 } 636 } 637 return val 638 } 639 640 func IndirectString(val interface{}) string { 641 if val == nil { 642 return "nil" 643 } 644 rval := reflect.ValueOf(val) 645 if rval.Kind() == reflect.Ptr && rval.IsNil() { 646 return "nil" 647 } 648 return fmt.Sprintf("%v", reflect.Indirect(rval).Interface()) 649 }