diff --git a/api.go b/api.go index e43c6f1..5650fbf 100644 --- a/api.go +++ b/api.go @@ -1,25 +1,20 @@ package bond import ( - //"io" + "io" "encoding/json" "net/http" "net/url" "fmt" -) - -type ContentType string - -const ( - PlainText ContentType = "text/plain; charset=utf-8" + "github.com/di4f/bond/contents" ) type Decoder interface { Decode(any) error } -type ApiFunc func(*Context) -func (fn ApiFunc) ServeHTTP(w ResponseWriter, r *Request) { +type Func func(*Context) +func (fn Func) ServeHTTP(w ResponseWriter, r *Request) { fn(&Context{ R: r, W: w, @@ -31,14 +26,16 @@ type Context struct { W ResponseWriter // Custom data to store stuff. Data any + + scanErr error dec Decoder } -func (c *Context) SetContentType(typ ContentType) { +func (c *Context) SetContentType(typ contents.Type) { c.SetHeader("Content-Type", string(typ)) } -func (c *Context) ContentType() string { +func (c *Context) ContentType() contents.Type { ret, ok := c.Header("Content-Type") if !ok { return "" @@ -46,7 +43,7 @@ func (c *Context) ContentType() string { if len(ret) < 1 { return "" } - return ret[0] + return contents.Type(ret[0]) } func (c *Context) SetHeader(k, v string) { @@ -65,21 +62,29 @@ func (c *Context) Close() { // Scan the incoming value from body depending // on the content type of the request. -func (c *Context) Scan(v any) error { +func (c *Context) Scan(v any) bool { if c.dec == nil { typ := c.ContentType() switch typ { - case "application/json" : + case contents.Json : c.dec = json.NewDecoder(c.R.Body) default: - return UnknownContentTypeErr + c.scanErr = UnknownContentTypeErr + return false } } err := c.dec.Decode(v) if err != nil { - return err + if err != io.EOF { + c.scanErr = err + } + return false } - return nil + return true +} + +func (c *Context) ScanErr() error { + return c.scanErr } func (c *Context) Path() string { diff --git a/cmd/test/main.go b/cmd/test/main.go index fcab9f6..844da8c 100644 --- a/cmd/test/main.go +++ b/cmd/test/main.go @@ -2,25 +2,32 @@ package main import ( "github.com/di4f/bond" + "github.com/di4f/bond/methods" + "github.com/di4f/bond/contents" ) +type GetNotesOptions struct { + Id int `json:"id"` + Name string `json:"name"` +} + var root = bond.Mux(). Def( "", - bond.ApiFunc(func(c *bond.Context) { + bond.Func(func(c *bond.Context) { c.W.Write([]byte("This is the index page")) }), ).Def( "hello", bond.Mux().Def( "en", - bond.ApiFunc(func(c *bond.Context) { - c.W.Write([]byte("Hello, World!")) + bond.Func(func(c *bond.Context) { + c.Printf("Hello, World!") }), ).Def( "ru", - bond.ApiFunc(func(c *bond.Context) { - c.W.Write([]byte("Привет, Мир!")) + bond.Func(func(c *bond.Context) { + c.Printf("Привет, Мир!") }), ), ).Def( @@ -28,8 +35,8 @@ var root = bond.Mux(). bond.Static("./static"), ).Def( "test", - bond.ApiFunc(func(c *bond.Context) { - c.SetContentType(bond.PlainText) + bond.Func(func(c *bond.Context) { + c.SetContentType(contents.Plain) c.Printf( "Path: %q\n"+ "Content-Type: %q\n", @@ -43,6 +50,16 @@ var root = bond.Mux(). } } }), +).Def( + "get-notes", + bond.Method().Def( + methods.Get, + bond.Func(func(c *bond.Context){ + opts := GetNotesOptions{} + c.Scan(&opts) + c.Printf("%v", opts) + }), + ), ) func main() {