ss/api.go

108 lines
1.7 KiB
Go
Raw Normal View History

2023-12-07 16:55:23 +03:00
package bond
import (
2024-01-03 21:23:03 +03:00
"io"
2023-12-07 16:55:23 +03:00
"encoding/json"
"net/http"
"net/url"
"fmt"
2024-01-09 07:40:32 +03:00
"vultras.su/core/bond/contents"
2023-12-07 16:55:23 +03:00
)
type Decoder interface {
Decode(any) error
}
2024-01-03 21:23:03 +03:00
type Func func(*Context)
2024-01-09 07:40:32 +03:00
2024-01-03 21:23:03 +03:00
func (fn Func) ServeHTTP(w ResponseWriter, r *Request) {
2023-12-07 16:55:23 +03:00
fn(&Context{
R: r,
W: w,
})
}
type Context struct {
R *Request
W ResponseWriter
// Custom data to store stuff.
Data any
2024-01-03 21:23:03 +03:00
scanErr error
2024-01-09 07:40:32 +03:00
dec Decoder
2023-12-07 16:55:23 +03:00
}
2024-01-03 21:23:03 +03:00
func (c *Context) SetContentType(typ contents.Type) {
2023-12-07 16:55:23 +03:00
c.SetHeader("Content-Type", string(typ))
}
2024-01-03 21:23:03 +03:00
func (c *Context) ContentType() contents.Type {
2023-12-07 16:55:23 +03:00
ret, ok := c.Header("Content-Type")
if !ok {
return ""
}
if len(ret) < 1 {
return ""
}
2024-01-03 21:23:03 +03:00
return contents.Type(ret[0])
2023-12-07 16:55:23 +03:00
}
func (c *Context) SetHeader(k, v string) {
c.W.Header().Set(k, v)
}
func (c *Context) Header(name string) ([]string, bool) {
ret, ok := c.R.Header[name]
return ret, ok
}
// Closes the requests body after finishes scaning.
func (c *Context) Close() {
c.R.Body.Close()
}
// Scan the incoming value from body depending
// on the content type of the request.
2024-01-03 21:23:03 +03:00
func (c *Context) Scan(v any) bool {
2023-12-07 16:55:23 +03:00
if c.dec == nil {
typ := c.ContentType()
switch typ {
2024-01-09 07:40:32 +03:00
case contents.Json:
2023-12-07 16:55:23 +03:00
c.dec = json.NewDecoder(c.R.Body)
2024-01-10 18:23:02 +03:00
//case contents.UrlEncoded:
// return false
2023-12-07 16:55:23 +03:00
default:
2024-01-03 21:23:03 +03:00
c.scanErr = UnknownContentTypeErr
return false
2023-12-07 16:55:23 +03:00
}
}
err := c.dec.Decode(v)
if err != nil {
2024-01-03 21:23:03 +03:00
if err != io.EOF {
c.scanErr = err
}
return false
2023-12-07 16:55:23 +03:00
}
2024-01-03 21:23:03 +03:00
return true
}
func (c *Context) ScanErr() error {
return c.scanErr
2023-12-07 16:55:23 +03:00
}
func (c *Context) Path() string {
return c.R.URL.Path
}
func (c *Context) NotFound() {
http.NotFound(c.W, c.R)
}
func (c *Context) Printf(format string, v ...any) (int, error) {
return fmt.Fprintf(c.W, format, v...)
}
func (c *Context) Query() url.Values {
return c.R.URL.Query()
}