github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/httplib/trans_to_req.go (about) 1 package httplib 2 3 import ( 4 "go/ast" 5 "reflect" 6 7 "github.com/gin-gonic/gin" 8 "github.com/sirupsen/logrus" 9 10 "github.com/artisanhe/tools/courier/transport_http/transform" 11 "github.com/artisanhe/tools/reflectx" 12 ) 13 14 type Request interface { 15 Handle(c *gin.Context) 16 } 17 18 func TypeOfRequest(request Request) reflect.Type { 19 requestInterface := reflect.Indirect(reflect.ValueOf(request)).Interface() 20 return reflect.Indirect(reflect.ValueOf(requestInterface)).Type() 21 } 22 23 func TransToReq(c *gin.Context, reqModel interface{}) error { 24 reflectValue := reflect.ValueOf(reqModel) 25 return TransToReqByReflectValue(c, reflectValue) 26 } 27 28 func TransToReqByReflectValue(c *gin.Context, rv reflect.Value) error { 29 group := transform.ParameterGroupFromReflectValue(rv) 30 return transform.MarshalParameters(group, &ParameterValuesGetter{ 31 ParameterValuesGetter: transform.NewParameterValuesGetter(c.Request), 32 Group: group, 33 C: c, 34 }) 35 } 36 37 type ParameterValuesGetter struct { 38 *transform.ParameterValuesGetter 39 Group *transform.ParameterGroup 40 C *gin.Context 41 } 42 43 func (getter *ParameterValuesGetter) Initial() error { 44 if getter.Group.Context.Len() > 0 { 45 for _, parameterMeta := range getter.Group.Context { 46 contextValue, contextExists := getter.C.Get(parameterMeta.Name) 47 if !contextExists { 48 logrus.Panicf("read req %s context failed!", parameterMeta.Name) 49 } 50 reflectx.SetValue(parameterMeta.Value, parameterMeta.Field.Type, contextValue) 51 } 52 } 53 return getter.ParameterValuesGetter.Initial() 54 } 55 56 func (getter *ParameterValuesGetter) Param(name string) string { 57 return getter.C.Param(name) 58 } 59 60 func checkRequestTypeSettings(tpe reflect.Type) { 61 for tpe.Kind() == reflect.Ptr { 62 tpe = tpe.Elem() 63 } 64 65 for i := 0; i < tpe.NumField(); i++ { 66 field := tpe.Field(i) 67 if !ast.IsExported(field.Name) { 68 continue 69 } 70 71 if field.Anonymous { 72 checkRequestTypeSettings(field.Type) 73 continue 74 } 75 76 _, exists := field.Tag.Lookup("in") 77 if !exists { 78 logrus.Panicf("missing tag `in` on struct field `%s.%s[%s]`", tpe.PkgPath(), tpe.Name(), field.Name) 79 } 80 } 81 } 82 83 func FromRequest(request Request) gin.HandlerFunc { 84 requestType := TypeOfRequest(request) 85 checkRequestTypeSettings(requestType) 86 87 return func(c *gin.Context) { 88 requestReflectValue := reflect.New(requestType) 89 90 err := TransToReqByReflectValue(c, requestReflectValue) 91 92 if err != nil { 93 WriteError(c, err) 94 c.Abort() 95 return 96 } 97 98 requestReflectValue.Interface().(Request).Handle(c) 99 } 100 }