form_mapping.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. // Copyright 2014 Manu Martinez-Almeida. All rights reserved.
  2. // Use of this source code is governed by a MIT style
  3. // license that can be found in the LICENSE file.
  4. package binding
  5. import (
  6. "encoding/json"
  7. "errors"
  8. "reflect"
  9. "strconv"
  10. "strings"
  11. "time"
  12. )
  13. var errUnknownType = errors.New("Unknown type")
  14. func mapUri(ptr interface{}, m map[string][]string) error {
  15. return mapFormByTag(ptr, m, "uri")
  16. }
  17. func mapForm(ptr interface{}, form map[string][]string) error {
  18. return mapFormByTag(ptr, form, "form")
  19. }
  20. var emptyField = reflect.StructField{}
  21. func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error {
  22. _, err := mapping(reflect.ValueOf(ptr), emptyField, form, tag)
  23. return err
  24. }
  25. func mapping(value reflect.Value, field reflect.StructField, form map[string][]string, tag string) (bool, error) {
  26. var vKind = value.Kind()
  27. if vKind == reflect.Ptr {
  28. var isNew bool
  29. vPtr := value
  30. if value.IsNil() {
  31. isNew = true
  32. vPtr = reflect.New(value.Type().Elem())
  33. }
  34. isSetted, err := mapping(vPtr.Elem(), field, form, tag)
  35. if err != nil {
  36. return false, err
  37. }
  38. if isNew && isSetted {
  39. value.Set(vPtr)
  40. }
  41. return isSetted, nil
  42. }
  43. ok, err := tryToSetValue(value, field, form, tag)
  44. if err != nil {
  45. return false, err
  46. }
  47. if ok {
  48. return true, nil
  49. }
  50. if vKind == reflect.Struct {
  51. tValue := value.Type()
  52. var isSetted bool
  53. for i := 0; i < value.NumField(); i++ {
  54. if !value.Field(i).CanSet() {
  55. continue
  56. }
  57. ok, err := mapping(value.Field(i), tValue.Field(i), form, tag)
  58. if err != nil {
  59. return false, err
  60. }
  61. isSetted = isSetted || ok
  62. }
  63. return isSetted, nil
  64. }
  65. return false, nil
  66. }
  67. func tryToSetValue(value reflect.Value, field reflect.StructField, form map[string][]string, tag string) (bool, error) {
  68. var tagValue, defaultValue string
  69. var isDefaultExists bool
  70. tagValue = field.Tag.Get(tag)
  71. tagValue, opts := head(tagValue, ",")
  72. if tagValue == "-" { // just ignoring this field
  73. return false, nil
  74. }
  75. if tagValue == "" { // default value is FieldName
  76. tagValue = field.Name
  77. }
  78. if tagValue == "" { // when field is "emptyField" variable
  79. return false, nil
  80. }
  81. var opt string
  82. for len(opts) > 0 {
  83. opt, opts = head(opts, ",")
  84. k, v := head(opt, "=")
  85. switch k {
  86. case "default":
  87. isDefaultExists = true
  88. defaultValue = v
  89. }
  90. }
  91. vs, ok := form[tagValue]
  92. if !ok && !isDefaultExists {
  93. return false, nil
  94. }
  95. switch value.Kind() {
  96. case reflect.Slice:
  97. if !ok {
  98. vs = []string{defaultValue}
  99. }
  100. return true, setSlice(vs, value, field)
  101. default:
  102. var val string
  103. if !ok {
  104. val = defaultValue
  105. }
  106. if len(vs) > 0 {
  107. val = vs[0]
  108. }
  109. return true, setWithProperType(val, value, field)
  110. }
  111. }
  112. func setWithProperType(val string, value reflect.Value, field reflect.StructField) error {
  113. switch value.Kind() {
  114. case reflect.Int:
  115. return setIntField(val, 0, value)
  116. case reflect.Int8:
  117. return setIntField(val, 8, value)
  118. case reflect.Int16:
  119. return setIntField(val, 16, value)
  120. case reflect.Int32:
  121. return setIntField(val, 32, value)
  122. case reflect.Int64:
  123. return setIntField(val, 64, value)
  124. case reflect.Uint:
  125. return setUintField(val, 0, value)
  126. case reflect.Uint8:
  127. return setUintField(val, 8, value)
  128. case reflect.Uint16:
  129. return setUintField(val, 16, value)
  130. case reflect.Uint32:
  131. return setUintField(val, 32, value)
  132. case reflect.Uint64:
  133. return setUintField(val, 64, value)
  134. case reflect.Bool:
  135. return setBoolField(val, value)
  136. case reflect.Float32:
  137. return setFloatField(val, 32, value)
  138. case reflect.Float64:
  139. return setFloatField(val, 64, value)
  140. case reflect.String:
  141. value.SetString(val)
  142. case reflect.Struct:
  143. switch value.Interface().(type) {
  144. case time.Time:
  145. return setTimeField(val, field, value)
  146. }
  147. return json.Unmarshal([]byte(val), value.Addr().Interface())
  148. case reflect.Map:
  149. return json.Unmarshal([]byte(val), value.Addr().Interface())
  150. default:
  151. return errUnknownType
  152. }
  153. return nil
  154. }
  155. func setIntField(val string, bitSize int, field reflect.Value) error {
  156. if val == "" {
  157. val = "0"
  158. }
  159. intVal, err := strconv.ParseInt(val, 10, bitSize)
  160. if err == nil {
  161. field.SetInt(intVal)
  162. }
  163. return err
  164. }
  165. func setUintField(val string, bitSize int, field reflect.Value) error {
  166. if val == "" {
  167. val = "0"
  168. }
  169. uintVal, err := strconv.ParseUint(val, 10, bitSize)
  170. if err == nil {
  171. field.SetUint(uintVal)
  172. }
  173. return err
  174. }
  175. func setBoolField(val string, field reflect.Value) error {
  176. if val == "" {
  177. val = "false"
  178. }
  179. boolVal, err := strconv.ParseBool(val)
  180. if err == nil {
  181. field.SetBool(boolVal)
  182. }
  183. return err
  184. }
  185. func setFloatField(val string, bitSize int, field reflect.Value) error {
  186. if val == "" {
  187. val = "0.0"
  188. }
  189. floatVal, err := strconv.ParseFloat(val, bitSize)
  190. if err == nil {
  191. field.SetFloat(floatVal)
  192. }
  193. return err
  194. }
  195. func setTimeField(val string, structField reflect.StructField, value reflect.Value) error {
  196. timeFormat := structField.Tag.Get("time_format")
  197. if timeFormat == "" {
  198. timeFormat = time.RFC3339
  199. }
  200. if val == "" {
  201. value.Set(reflect.ValueOf(time.Time{}))
  202. return nil
  203. }
  204. l := time.Local
  205. if isUTC, _ := strconv.ParseBool(structField.Tag.Get("time_utc")); isUTC {
  206. l = time.UTC
  207. }
  208. if locTag := structField.Tag.Get("time_location"); locTag != "" {
  209. loc, err := time.LoadLocation(locTag)
  210. if err != nil {
  211. return err
  212. }
  213. l = loc
  214. }
  215. t, err := time.ParseInLocation(timeFormat, val, l)
  216. if err != nil {
  217. return err
  218. }
  219. value.Set(reflect.ValueOf(t))
  220. return nil
  221. }
  222. func setSlice(vals []string, value reflect.Value, field reflect.StructField) error {
  223. slice := reflect.MakeSlice(value.Type(), len(vals), len(vals))
  224. for i, s := range vals {
  225. err := setWithProperType(s, slice.Index(i), field)
  226. if err != nil {
  227. return err
  228. }
  229. }
  230. value.Set(slice)
  231. return nil
  232. }
  233. func head(str, sep string) (head string, tail string) {
  234. idx := strings.Index(str, sep)
  235. if idx < 0 {
  236. return str, ""
  237. }
  238. return str[:idx], str[idx+len(sep):]
  239. }