feat: added the scanning for context.

This commit is contained in:
Andrey Parhomenko 2024-01-03 21:23:03 +03:00
parent 987da305b8
commit b4183239f7
2 changed files with 46 additions and 24 deletions

39
api.go
View file

@ -1,25 +1,20 @@
package bond package bond
import ( import (
//"io" "io"
"encoding/json" "encoding/json"
"net/http" "net/http"
"net/url" "net/url"
"fmt" "fmt"
) "github.com/di4f/bond/contents"
type ContentType string
const (
PlainText ContentType = "text/plain; charset=utf-8"
) )
type Decoder interface { type Decoder interface {
Decode(any) error Decode(any) error
} }
type ApiFunc func(*Context) type Func func(*Context)
func (fn ApiFunc) ServeHTTP(w ResponseWriter, r *Request) { func (fn Func) ServeHTTP(w ResponseWriter, r *Request) {
fn(&Context{ fn(&Context{
R: r, R: r,
W: w, W: w,
@ -31,14 +26,16 @@ type Context struct {
W ResponseWriter W ResponseWriter
// Custom data to store stuff. // Custom data to store stuff.
Data any Data any
scanErr error
dec Decoder dec Decoder
} }
func (c *Context) SetContentType(typ ContentType) { func (c *Context) SetContentType(typ contents.Type) {
c.SetHeader("Content-Type", string(typ)) c.SetHeader("Content-Type", string(typ))
} }
func (c *Context) ContentType() string { func (c *Context) ContentType() contents.Type {
ret, ok := c.Header("Content-Type") ret, ok := c.Header("Content-Type")
if !ok { if !ok {
return "" return ""
@ -46,7 +43,7 @@ func (c *Context) ContentType() string {
if len(ret) < 1 { if len(ret) < 1 {
return "" return ""
} }
return ret[0] return contents.Type(ret[0])
} }
func (c *Context) SetHeader(k, v string) { func (c *Context) SetHeader(k, v string) {
@ -65,21 +62,29 @@ func (c *Context) Close() {
// Scan the incoming value from body depending // Scan the incoming value from body depending
// on the content type of the request. // 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 { if c.dec == nil {
typ := c.ContentType() typ := c.ContentType()
switch typ { switch typ {
case "application/json" : case contents.Json :
c.dec = json.NewDecoder(c.R.Body) c.dec = json.NewDecoder(c.R.Body)
default: default:
return UnknownContentTypeErr c.scanErr = UnknownContentTypeErr
return false
} }
} }
err := c.dec.Decode(v) err := c.dec.Decode(v)
if err != nil { 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 { func (c *Context) Path() string {

View file

@ -2,25 +2,32 @@ package main
import ( import (
"github.com/di4f/bond" "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(). var root = bond.Mux().
Def( Def(
"", "",
bond.ApiFunc(func(c *bond.Context) { bond.Func(func(c *bond.Context) {
c.W.Write([]byte("This is the index page")) c.W.Write([]byte("This is the index page"))
}), }),
).Def( ).Def(
"hello", "hello",
bond.Mux().Def( bond.Mux().Def(
"en", "en",
bond.ApiFunc(func(c *bond.Context) { bond.Func(func(c *bond.Context) {
c.W.Write([]byte("Hello, World!")) c.Printf("Hello, World!")
}), }),
).Def( ).Def(
"ru", "ru",
bond.ApiFunc(func(c *bond.Context) { bond.Func(func(c *bond.Context) {
c.W.Write([]byte("Привет, Мир!")) c.Printf("Привет, Мир!")
}), }),
), ),
).Def( ).Def(
@ -28,8 +35,8 @@ var root = bond.Mux().
bond.Static("./static"), bond.Static("./static"),
).Def( ).Def(
"test", "test",
bond.ApiFunc(func(c *bond.Context) { bond.Func(func(c *bond.Context) {
c.SetContentType(bond.PlainText) c.SetContentType(contents.Plain)
c.Printf( c.Printf(
"Path: %q\n"+ "Path: %q\n"+
"Content-Type: %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() { func main() {