context.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package cli
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "git.nspix.com/golang/micro/utils/helper"
  7. "reflect"
  8. "strconv"
  9. "sync"
  10. )
  11. var (
  12. ErrInvalidStruct = errors.New("invalid struct")
  13. ErrInvalidArgument = errors.New("invalid argument")
  14. )
  15. type Context struct {
  16. ID int32
  17. CmdStr string
  18. Args []string //所有参数
  19. locker sync.RWMutex
  20. Values map[string]interface{}
  21. response *Response
  22. }
  23. func (ctx *Context) reset(s string) {
  24. ctx.response = &Response{}
  25. ctx.Args = nil
  26. ctx.CmdStr = s
  27. }
  28. func (ctx *Context) Get(s string) interface{} {
  29. ctx.locker.RLock()
  30. defer ctx.locker.RUnlock()
  31. if ctx.Values == nil {
  32. return ""
  33. }
  34. return ctx.Values[s]
  35. }
  36. func (ctx *Context) Set(key string, value interface{}) {
  37. ctx.locker.Lock()
  38. defer ctx.locker.Unlock()
  39. if ctx.Values == nil {
  40. ctx.Values = make(map[string]interface{})
  41. }
  42. ctx.Values[key] = value
  43. }
  44. func (ctx *Context) Bind(i interface{}) (err error) {
  45. refVal := reflect.Indirect(reflect.ValueOf(i))
  46. refType := refVal.Type()
  47. if refVal.Kind() != reflect.Struct {
  48. return ErrInvalidStruct
  49. }
  50. numOfField := refVal.Type().NumField()
  51. if numOfField != len(ctx.Args) {
  52. var usage string
  53. usage = "Usage: " + ctx.CmdStr + " "
  54. for i := 0; i < numOfField; i++ {
  55. usage += "{" + helper.LowerFirst(refType.Field(i).Name) + "|" + refVal.Field(i).Type().Kind().String() + "} "
  56. }
  57. ctx.Set("usage", usage)
  58. return ErrInvalidArgument
  59. }
  60. for i := 0; i < numOfField; i++ {
  61. switch refVal.Field(i).Kind() {
  62. case reflect.String:
  63. refVal.Field(i).SetString(ctx.Args[i])
  64. case reflect.Int, reflect.Int32, reflect.Int64:
  65. n, _ := strconv.ParseInt(ctx.Args[i], 10, 64)
  66. refVal.Field(i).SetInt(n)
  67. case reflect.Float32, reflect.Float64:
  68. n, _ := strconv.ParseFloat(ctx.Args[i], 64)
  69. refVal.Field(i).SetFloat(n)
  70. default:
  71. err = fmt.Errorf("unsupported argument %d kind %s", i, refVal.Field(i).Kind())
  72. return
  73. }
  74. }
  75. return
  76. }
  77. func (ctx *Context) Error(code int, msg string) (err error) {
  78. ctx.response.Code = code
  79. ctx.response.Error = msg
  80. return
  81. }
  82. func (ctx *Context) Success(i interface{}) (err error) {
  83. refVal := reflect.Indirect(reflect.ValueOf(i))
  84. switch refVal.Kind() {
  85. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  86. ctx.response.Data = []byte(strconv.FormatInt(refVal.Int(), 10))
  87. case reflect.Float32, reflect.Float64:
  88. ctx.response.Data = []byte(strconv.FormatFloat(refVal.Float(), 'f', -1, 64))
  89. case reflect.String:
  90. ctx.response.Data = []byte(refVal.String())
  91. case reflect.Slice:
  92. if refVal.Type().Elem().Kind() == reflect.Uint8 {
  93. ctx.response.Data = refVal.Bytes()
  94. } else {
  95. ctx.response.Data, err = json.MarshalIndent(refVal.Interface(), "", "\t")
  96. }
  97. case reflect.Struct, reflect.Map:
  98. ctx.response.Data, err = json.MarshalIndent(refVal.Interface(), "", "\t")
  99. default:
  100. ctx.response.Data, err = json.MarshalIndent(refVal.Interface(), "", "\t")
  101. }
  102. return
  103. }