encoding.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. package util
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "log"
  6. "net/url"
  7. "reflect"
  8. "strconv"
  9. "time"
  10. )
  11. //ConvertToQueryValues converts the struct to url.Values
  12. func ConvertToQueryValues(ifc interface{}) url.Values {
  13. values := url.Values{}
  14. SetQueryValues(ifc, &values)
  15. return values
  16. }
  17. //SetQueryValues sets the struct to existing url.Values following ECS encoding rules
  18. func SetQueryValues(ifc interface{}, values *url.Values) {
  19. setQueryValues(ifc, values, "")
  20. }
  21. func setQueryValues(i interface{}, values *url.Values, prefix string) {
  22. // add to support url.Values
  23. mapValues, ok := i.(url.Values)
  24. if ok {
  25. for k, _ := range mapValues {
  26. values.Set(k, mapValues.Get(k))
  27. }
  28. return
  29. }
  30. elem := reflect.ValueOf(i)
  31. if elem.Kind() == reflect.Ptr {
  32. elem = elem.Elem()
  33. }
  34. elemType := elem.Type()
  35. for i := 0; i < elem.NumField(); i++ {
  36. fieldName := elemType.Field(i).Name
  37. anonymous := elemType.Field(i).Anonymous
  38. field := elem.Field(i)
  39. // TODO Use Tag for validation
  40. // tag := typ.Field(i).Tag.Get("tagname")
  41. kind := field.Kind()
  42. if (kind == reflect.Ptr || kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map || kind == reflect.Chan) && field.IsNil() {
  43. continue
  44. }
  45. if kind == reflect.Ptr {
  46. field = field.Elem()
  47. kind = field.Kind()
  48. }
  49. var value string
  50. //switch field.Interface().(type) {
  51. switch kind {
  52. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  53. i := field.Int()
  54. if i != 0 {
  55. value = strconv.FormatInt(i, 10)
  56. }
  57. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  58. i := field.Uint()
  59. if i != 0 {
  60. value = strconv.FormatUint(i, 10)
  61. }
  62. case reflect.Float32:
  63. value = strconv.FormatFloat(field.Float(), 'f', 4, 32)
  64. case reflect.Float64:
  65. value = strconv.FormatFloat(field.Float(), 'f', 4, 64)
  66. case reflect.Bool:
  67. value = strconv.FormatBool(field.Bool())
  68. case reflect.String:
  69. value = field.String()
  70. case reflect.Map:
  71. ifc := field.Interface()
  72. m := ifc.(map[string]string)
  73. if m != nil {
  74. j := 0
  75. for k, v := range m {
  76. j++
  77. keyName := fmt.Sprintf("%s.%d.Key", fieldName, j)
  78. values.Set(keyName, k)
  79. valueName := fmt.Sprintf("%s.%d.Value", fieldName, j)
  80. values.Set(valueName, v)
  81. }
  82. }
  83. case reflect.Slice:
  84. switch field.Type().Elem().Kind() {
  85. case reflect.Uint8:
  86. value = string(field.Bytes())
  87. case reflect.String:
  88. l := field.Len()
  89. if l > 0 {
  90. strArray := make([]string, l)
  91. for i := 0; i < l; i++ {
  92. strArray[i] = field.Index(i).String()
  93. }
  94. bytes, err := json.Marshal(strArray)
  95. if err == nil {
  96. value = string(bytes)
  97. } else {
  98. log.Printf("Failed to convert JSON: %v", err)
  99. }
  100. }
  101. default:
  102. l := field.Len()
  103. for j := 0; j < l; j++ {
  104. prefixName := fmt.Sprintf("%s.%d.", fieldName, (j + 1))
  105. ifc := field.Index(j).Interface()
  106. //log.Printf("%s : %v", prefixName, ifc)
  107. if ifc != nil {
  108. setQueryValues(ifc, values, prefixName)
  109. }
  110. }
  111. continue
  112. }
  113. default:
  114. switch field.Interface().(type) {
  115. case ISO6801Time:
  116. t := field.Interface().(ISO6801Time)
  117. value = t.String()
  118. case time.Time:
  119. t := field.Interface().(time.Time)
  120. value = GetISO8601TimeStamp(t)
  121. default:
  122. ifc := field.Interface()
  123. if ifc != nil {
  124. if anonymous {
  125. SetQueryValues(ifc, values)
  126. } else {
  127. prefixName := fieldName + "."
  128. setQueryValues(ifc, values, prefixName)
  129. }
  130. continue
  131. }
  132. }
  133. }
  134. if value != "" {
  135. name := elemType.Field(i).Tag.Get("ArgName")
  136. if name == "" {
  137. name = fieldName
  138. }
  139. if prefix != "" {
  140. name = prefix + name
  141. }
  142. values.Set(name, value)
  143. }
  144. }
  145. }