fmt_plus.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package utils
  2. import (
  3. "reflect"
  4. "strconv"
  5. "strings"
  6. "github.com/dablelv/go-huge-util/conv"
  7. jsoniter "github.com/json-iterator/go"
  8. "github.com/pkg/errors"
  9. "golang.org/x/exp/constraints"
  10. )
  11. var ComplexType = []reflect.Kind{reflect.Struct, reflect.Map, reflect.Slice, reflect.Array}
  12. // StructToMap 利用反射将结构体转化为map
  13. func StructToMap(structInfo any, tag string, stringify bool) (map[string]any, error) {
  14. val := reflect.Indirect(reflect.ValueOf(structInfo))
  15. smap := make(map[string]any)
  16. if err := ReflectToMap(smap, val, tag, stringify); err != nil {
  17. return nil, err
  18. }
  19. return smap, nil
  20. }
  21. // ReflectToMap 结构体反射转化成Map
  22. func ReflectToMap(smap map[string]any, val reflect.Value, tag string, stringify bool) error {
  23. typ := val.Type()
  24. if typ.Kind() != reflect.Struct {
  25. return errors.New("expect struct")
  26. }
  27. for i := 0; i < typ.NumField(); i++ {
  28. typField := typ.Field(i)
  29. if !typField.IsExported() {
  30. continue
  31. }
  32. if typField.Anonymous && typField.Type.Kind() == reflect.Struct {
  33. if err := ReflectToMap(smap, val.Field(i), tag, stringify); err != nil {
  34. return err
  35. }
  36. }
  37. tagName := typ.Field(i).Tag.Get(tag)
  38. if tagName == "" {
  39. continue
  40. }
  41. if stringify && IsComplexType(typField.Type) {
  42. marshal, err := jsoniter.Marshal(val.Field(i).Interface())
  43. if err != nil {
  44. return err
  45. }
  46. smap[tagName] = marshal
  47. } else {
  48. smap[tagName] = val.Field(i).Interface()
  49. }
  50. }
  51. return nil
  52. }
  53. // ArrayToMap 将数组转化为Map
  54. func ArrayToMap[T constraints.Ordered](array []T) map[string]any {
  55. mapArr := make(map[string]any, len(array))
  56. for i := 0; i < len(array); i++ {
  57. mapArr[strconv.Itoa(i)] = array[i]
  58. }
  59. return mapArr
  60. }
  61. // Indirect 若是指针 返回指针指向的 Value Type ; 不是指针直接返回 Value Type
  62. func Indirect(args any) (reflect.Value, reflect.Type) {
  63. val := reflect.ValueOf(args)
  64. typ := reflect.TypeOf(args)
  65. // 若是指针则取指针指向的值
  66. if val.Kind() == reflect.Ptr {
  67. val = val.Elem()
  68. typ = val.Type()
  69. }
  70. return val, typ
  71. }
  72. // Implode Join array elements with a string
  73. func Implode[T any](elems []T, sep string) string {
  74. joinEle := make([]string, 0, len(elems))
  75. for i := 0; i < len(elems); i++ {
  76. joinEle = append(joinEle, conv.ToAny[string](elems[i]))
  77. }
  78. return strings.Join(joinEle, sep)
  79. }
  80. // Explode Split a string by a string
  81. func Explode[T constraints.Ordered](dest *[]T, s string, sep string) (err error) {
  82. elems := strings.Split(s, sep)
  83. var elem T
  84. *dest = make([]T, 0, len(elems))
  85. for i := 0; i < len(elems); i++ {
  86. if elems[i] == "" {
  87. continue
  88. }
  89. if elem, err = conv.ToAnyE[T](elems[i]); err != nil {
  90. return err
  91. }
  92. *dest = append(*dest, elem)
  93. }
  94. return err
  95. }
  96. // TrimSpace 去除结构体空格
  97. // @param: target interface (target: 目标结构体,传入必须是指针类型)
  98. // @return: null
  99. func TrimSpace(target any) {
  100. t := reflect.TypeOf(target)
  101. if t.Kind() != reflect.Ptr {
  102. return
  103. }
  104. t = t.Elem()
  105. v := reflect.ValueOf(target).Elem()
  106. for i := 0; i < t.NumField(); i++ {
  107. switch v.Field(i).Kind() {
  108. case reflect.String:
  109. v.Field(i).SetString(strings.TrimSpace(v.Field(i).String()))
  110. }
  111. }
  112. }