parsers.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package param
  2. import (
  3. "encoding/json"
  4. "reflect"
  5. "strconv"
  6. "strings"
  7. "time"
  8. )
  9. type paramParser interface {
  10. parse(value string, toType reflect.Type) (interface{}, error)
  11. }
  12. func getParser(param *MethodParam, t reflect.Type) paramParser {
  13. switch t.Kind() {
  14. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
  15. reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  16. return intParser{}
  17. case reflect.Slice:
  18. if t.Elem().Kind() == reflect.Uint8 { //treat []byte as string
  19. return stringParser{}
  20. }
  21. if param.in == body {
  22. return jsonParser{}
  23. }
  24. elemParser := getParser(param, t.Elem())
  25. if elemParser == (jsonParser{}) {
  26. return elemParser
  27. }
  28. return sliceParser(elemParser)
  29. case reflect.Bool:
  30. return boolParser{}
  31. case reflect.String:
  32. return stringParser{}
  33. case reflect.Float32, reflect.Float64:
  34. return floatParser{}
  35. case reflect.Ptr:
  36. elemParser := getParser(param, t.Elem())
  37. if elemParser == (jsonParser{}) {
  38. return elemParser
  39. }
  40. return ptrParser(elemParser)
  41. default:
  42. if t.PkgPath() == "time" && t.Name() == "Time" {
  43. return timeParser{}
  44. }
  45. return jsonParser{}
  46. }
  47. }
  48. type parserFunc func(value string, toType reflect.Type) (interface{}, error)
  49. func (f parserFunc) parse(value string, toType reflect.Type) (interface{}, error) {
  50. return f(value, toType)
  51. }
  52. type boolParser struct {
  53. }
  54. func (p boolParser) parse(value string, toType reflect.Type) (interface{}, error) {
  55. return strconv.ParseBool(value)
  56. }
  57. type stringParser struct {
  58. }
  59. func (p stringParser) parse(value string, toType reflect.Type) (interface{}, error) {
  60. return value, nil
  61. }
  62. type intParser struct {
  63. }
  64. func (p intParser) parse(value string, toType reflect.Type) (interface{}, error) {
  65. return strconv.Atoi(value)
  66. }
  67. type floatParser struct {
  68. }
  69. func (p floatParser) parse(value string, toType reflect.Type) (interface{}, error) {
  70. if toType.Kind() == reflect.Float32 {
  71. res, err := strconv.ParseFloat(value, 32)
  72. if err != nil {
  73. return nil, err
  74. }
  75. return float32(res), nil
  76. }
  77. return strconv.ParseFloat(value, 64)
  78. }
  79. type timeParser struct {
  80. }
  81. func (p timeParser) parse(value string, toType reflect.Type) (result interface{}, err error) {
  82. result, err = time.Parse(time.RFC3339, value)
  83. if err != nil {
  84. result, err = time.Parse("2006-01-02", value)
  85. }
  86. return
  87. }
  88. type jsonParser struct {
  89. }
  90. func (p jsonParser) parse(value string, toType reflect.Type) (interface{}, error) {
  91. pResult := reflect.New(toType)
  92. v := pResult.Interface()
  93. err := json.Unmarshal([]byte(value), v)
  94. if err != nil {
  95. return nil, err
  96. }
  97. return pResult.Elem().Interface(), nil
  98. }
  99. func sliceParser(elemParser paramParser) paramParser {
  100. return parserFunc(func(value string, toType reflect.Type) (interface{}, error) {
  101. values := strings.Split(value, ",")
  102. result := reflect.MakeSlice(toType, 0, len(values))
  103. elemType := toType.Elem()
  104. for _, v := range values {
  105. parsedValue, err := elemParser.parse(v, elemType)
  106. if err != nil {
  107. return nil, err
  108. }
  109. result = reflect.Append(result, reflect.ValueOf(parsedValue))
  110. }
  111. return result.Interface(), nil
  112. })
  113. }
  114. func ptrParser(elemParser paramParser) paramParser {
  115. return parserFunc(func(value string, toType reflect.Type) (interface{}, error) {
  116. parsedValue, err := elemParser.parse(value, toType.Elem())
  117. if err != nil {
  118. return nil, err
  119. }
  120. newValPtr := reflect.New(toType.Elem())
  121. newVal := reflect.Indirect(newValPtr)
  122. convertedVal, err := safeConvert(reflect.ValueOf(parsedValue), toType.Elem())
  123. if err != nil {
  124. return nil, err
  125. }
  126. newVal.Set(convertedVal)
  127. return newValPtr.Interface(), nil
  128. })
  129. }