From 010e1942bb6acf62662de50e8889c0f7188a7dff Mon Sep 17 00:00:00 2001 From: tonnyzhang Date: Tue, 28 Sep 2021 15:38:40 +0800 Subject: [PATCH] feat: add method ShouldBindWidth/ShouldBindBodyWith/ShouldBindWithJSON/ShouldBindBodyWithJSON; close #21 --- binding/Binding.go | 19 +++++++++++++++++++ binding/json.go | 28 ++++++++++++++++++++++++++++ context_binding.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 binding/Binding.go create mode 100644 binding/json.go create mode 100644 context_binding.go diff --git a/binding/Binding.go b/binding/Binding.go new file mode 100644 index 0000000..0f1dad9 --- /dev/null +++ b/binding/Binding.go @@ -0,0 +1,19 @@ +package binding + +import "net/http" + +// IBinding Binding interface +type IBinding interface { + Bind(*http.Request, interface{}) error +} + +// IBindingBody bind body +type IBindingBody interface { + IBinding + BindBody([]byte, interface{}) error +} + +var ( + // JSON json binding + JSON = jsonBinding{} +) diff --git a/binding/json.go b/binding/json.go new file mode 100644 index 0000000..f135296 --- /dev/null +++ b/binding/json.go @@ -0,0 +1,28 @@ +package binding + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" +) + +type jsonBinding struct{} + +func (jsonBinding) Bind(req *http.Request, obj interface{}) (err error) { + if req == nil || req.Body == nil { + err = fmt.Errorf("bad request") + } else { + err = decodeJSON(req.Body, obj) + } + return +} +func (jsonBinding) BindBody(b []byte, obj interface{}) error { + return decodeJSON(bytes.NewBuffer(b), obj) +} + +func decodeJSON(r io.Reader, obj interface{}) error { + decoder := json.NewDecoder(r) + return decoder.Decode(obj) +} diff --git a/context_binding.go b/context_binding.go new file mode 100644 index 0000000..1664704 --- /dev/null +++ b/context_binding.go @@ -0,0 +1,43 @@ +package cotton + +import ( + "io/ioutil" + + "github.com/tonny-zhang/cotton/binding" +) + +// ShouldBindWith bind +func (ctx *Context) ShouldBindWith(obj interface{}, b binding.IBinding) error { + return b.Bind(ctx.Request, obj) +} + +// BodyBytesKey indicates a default body bytes key. +const BodyBytesKey = "cotton/bbk" + +// ShouldBindBodyWith bind body +func (ctx *Context) ShouldBindBodyWith(obj interface{}, bb binding.IBindingBody) (err error) { + var body []byte + if v, ok := ctx.Get(BodyBytesKey); ok { + if vv, ok := v.([]byte); ok { + body = vv + } + } + if body == nil { + body, err = ioutil.ReadAll(ctx.Request.Body) + if err != nil { + return + } + ctx.Set(BodyBytesKey, body) + } + return bb.BindBody(body, obj) +} + +// ShouldBindWithJSON bind with json +func (ctx *Context) ShouldBindWithJSON(obj interface{}) error { + return ctx.ShouldBindWith(obj, binding.JSON) +} + +// ShouldBindBodyWithJSON bind body with json +func (ctx *Context) ShouldBindBodyWithJSON(obj interface{}) (err error) { + return ctx.ShouldBindBodyWith(obj, binding.JSON) +}