package ginutil import ( "net/http" "reflect" "kpt-tmr-group/pkg/jsonpb" "kpt-tmr-group/pkg/xerr" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/golang/protobuf/proto" "github.com/huandu/xstrings" ) var camelQuery = &CamelQueryBinding{} // BindQuery with query params func BindQuery(c *gin.Context, obj interface{}) error { return c.ShouldBindWith(obj, camelQuery) } type CamelQueryBinding struct{} func (*CamelQueryBinding) Name() string { return "camel_query" } func (*CamelQueryBinding) Bind(req *http.Request, obj interface{}) error { values := req.URL.Query() if err := mapFormByTag(obj, values, "json"); err != nil { return err } return binding.Validator.ValidateStruct(obj) } type camelFormSource map[string][]string // TrySet tries to set a value by request's form source (like map[string][]string) func (form camelFormSource) TrySet(value reflect.Value, field reflect.StructField, tagValue string, opt setOptions) (isSetted bool, err error) { return setByForm(value, field, form, xstrings.FirstRuneToLower(xstrings.ToCamelCase(tagValue)), opt) } // BindProtoMessage with proto message from json body func BindProtoMessage(c *gin.Context, obj proto.Message) error { return c.ShouldBindWith(obj, protoMessageBindingFromBody) } var protoMessageBindingFromBody = &ProtoMessageBinding{} type ProtoMessageBinding struct{} func (*ProtoMessageBinding) Name() string { return "proto_message_binding" } func (*ProtoMessageBinding) Bind(req *http.Request, obj interface{}) error { pbMessage, ok := obj.(proto.Message) if !ok { return xerr.New("bind obj should be proto.Message") } if err := jsonpb.Unmarshal(req.Body, pbMessage); err != nil { return xerr.WithStack(err) } return binding.Validator.ValidateStruct(obj) }