Improved API

This commit is contained in:
2024-03-16 15:22:47 +01:00
parent d6de510d6e
commit f728e19976
10 changed files with 232 additions and 121 deletions

View File

@ -4,44 +4,42 @@ import (
"errors"
"io"
"net/http"
"unsafe"
"git.akyoto.dev/go/router"
)
// Context represents the interface for a request & response context.
type Context interface {
Copy(io.Reader) error
Bytes([]byte) error
Error(messages ...any) error
File(path string) error
Get(param string) string
Header(key string, value string)
Host() string
Method() string
Next() error
Path() string
Protocol() string
Reader(io.Reader) error
RequestHeader(key string) string
ResponseHeader(key string) string
Scheme() string
Request() Request
Response() Response
Status(status int) Context
String(string) error
Write([]byte) (int, error)
WriteString(string) (int, error)
}
// ctx represents a request & response context.
type ctx struct {
request *http.Request
response http.ResponseWriter
request request
response response
server *server
params []router.Parameter
handlerCount uint8
}
// Bytes responds with a raw byte slice.
func (c *ctx) Bytes(body []byte) error {
_, err := c.response.Write(body)
func (ctx *ctx) Bytes(body []byte) error {
_, err := ctx.response.Write(body)
return err
}
// Copy sends the contents of the io.Reader without creating an in-memory copy.
func (ctx *ctx) Copy(reader io.Reader) error {
_, err := io.Copy(ctx.response.ResponseWriter, reader)
return err
}
@ -74,56 +72,26 @@ func (ctx *ctx) Get(param string) string {
return ""
}
// File serves the file at the given path.
func (ctx *ctx) File(path string) error {
http.ServeFile(ctx.response.ResponseWriter, ctx.request.Request, path)
return nil
}
// Next executes the next handler in the middleware chain.
func (ctx *ctx) Next() error {
ctx.handlerCount++
return ctx.server.handlers[ctx.handlerCount](ctx)
}
// RequestHeader returns the request header value for the given key.
func (ctx *ctx) RequestHeader(key string) string {
return ctx.request.Header.Get(key)
// Request returns the HTTP request.
func (ctx *ctx) Request() Request {
return &ctx.request
}
// ResponseHeader returns the response header value for the given key.
func (ctx *ctx) ResponseHeader(key string) string {
return ctx.response.Header().Get(key)
}
// Header sets the header value for the given key.
func (ctx *ctx) Header(key string, value string) {
ctx.response.Header().Set(key, value)
}
// Method returns the request method.
func (ctx *ctx) Method() string {
return ctx.request.Method
}
// Protocol returns the request protocol.
func (ctx *ctx) Protocol() string {
return ctx.request.Proto
}
// Host returns the requested host.
func (ctx *ctx) Host() string {
return ctx.request.Host
}
// Path returns the requested path.
func (ctx *ctx) Path() string {
return ctx.request.URL.Path
}
// Reader sends the contents of the io.Reader without creating an in-memory copy.
func (ctx *ctx) Reader(reader io.Reader) error {
_, err := io.Copy(ctx.response, reader)
return err
}
// Scheme returns either `http` or `https`.
func (ctx *ctx) Scheme() string {
return ctx.request.URL.Scheme
// Response returns the HTTP response.
func (ctx *ctx) Response() Response {
return &ctx.response
}
// Status sets the HTTP status of the response.
@ -134,18 +102,8 @@ func (ctx *ctx) Status(status int) Context {
// String responds with the given string.
func (ctx *ctx) String(body string) error {
slice := unsafe.Slice(unsafe.StringData(body), len(body))
return ctx.Bytes(slice)
}
// Write implements the io.Writer interface.
func (ctx *ctx) Write(body []byte) (int, error) {
return ctx.response.Write(body)
}
// WriteString implements the io.StringWriter interface.
func (ctx *ctx) WriteString(body string) (int, error) {
return ctx.response.(io.StringWriter).WriteString(body)
_, err := ctx.response.WriteString(body)
return err
}
// addParameter adds a new parameter to the context.