binding.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package api
  2. import (
  3. "fmt"
  4. "github.com/gin-gonic/gin/binding"
  5. "reflect"
  6. "strings"
  7. "sync"
  8. )
  9. const (
  10. _ uint8 = iota
  11. json
  12. xml
  13. yaml
  14. form
  15. query
  16. )
  17. var constructor = &bindConstructor{}
  18. type bindConstructor struct {
  19. cache map[string][]uint8
  20. mux sync.Mutex
  21. }
  22. func (e *bindConstructor) GetBindingForGin(d interface{}) []binding.Binding {
  23. bs := e.getBinding(reflect.TypeOf(d).String())
  24. if bs == nil {
  25. //重新构建
  26. bs = e.resolve(d)
  27. }
  28. gbs := make([]binding.Binding, 0)
  29. mp := make(map[uint8]binding.Binding, 0)
  30. for _, b := range bs {
  31. switch b {
  32. case json:
  33. mp[json] = binding.JSON
  34. case xml:
  35. mp[xml] = binding.XML
  36. case yaml:
  37. mp[yaml] = binding.YAML
  38. case form:
  39. mp[form] = binding.Form
  40. case query:
  41. mp[query] = binding.Query
  42. default:
  43. mp[0] = nil
  44. }
  45. }
  46. for e := range mp {
  47. gbs=append(gbs, mp[e])
  48. }
  49. return gbs
  50. }
  51. func (e *bindConstructor) resolve(d interface{}) []uint8 {
  52. bs := make([]uint8, 0)
  53. qType := reflect.TypeOf(d).Elem()
  54. var tag reflect.StructTag
  55. var ok bool
  56. fmt.Println(qType.Kind())
  57. for i := 0; i < qType.NumField(); i++ {
  58. tag = qType.Field(i).Tag
  59. if _, ok = tag.Lookup("json"); ok {
  60. bs = append(bs, json)
  61. }
  62. if _, ok = tag.Lookup("xml"); ok {
  63. bs = append(bs, xml)
  64. }
  65. if _, ok = tag.Lookup("yaml"); ok {
  66. bs = append(bs, yaml)
  67. }
  68. if _, ok = tag.Lookup("form"); ok {
  69. bs = append(bs, form)
  70. }
  71. if _, ok = tag.Lookup("query"); ok {
  72. bs = append(bs, query)
  73. }
  74. if _, ok = tag.Lookup("uri"); ok {
  75. bs = append(bs, 0)
  76. }
  77. if t, ok := tag.Lookup("binding"); ok && strings.Index(t, "dive") > -1 {
  78. qValue := reflect.ValueOf(d)
  79. bs = append(bs, e.resolve(qValue.Field(i))...)
  80. continue
  81. }
  82. if t, ok := tag.Lookup("validate"); ok && strings.Index(t, "dive") > -1 {
  83. qValue := reflect.ValueOf(d)
  84. bs = append(bs, e.resolve(qValue.Field(i))...)
  85. }
  86. }
  87. return bs
  88. }
  89. func (e *bindConstructor) getBinding(name string) []uint8 {
  90. e.mux.Lock()
  91. defer e.mux.Unlock()
  92. return e.cache[name]
  93. }
  94. func (e *bindConstructor) setBinding(name string, bs []uint8) {
  95. e.mux.Lock()
  96. defer e.mux.Unlock()
  97. if e.cache == nil {
  98. e.cache = make(map[string][]uint8)
  99. }
  100. e.cache[name] = bs
  101. }