85 lines
1.9 KiB
Go

package web
import (
"errors"
)
// Context is the interface for a request and its response.
type Context interface {
Bytes([]byte) error
Error(...any) error
Next() error
Redirect(int, string) error
Request() Request
Response() Response
Status(int) Context
String(string) error
}
// context contains the request and response data.
type context struct {
request
response
server *server
handlerCount uint8
}
// Bytes adds the raw byte slice to the response body.
func (ctx *context) Bytes(body []byte) error {
ctx.response.body = append(ctx.response.body, body...)
return nil
}
// Error provides a convenient way to wrap multiple errors.
func (ctx *context) Error(messages ...any) error {
var combined []error
for _, msg := range messages {
switch err := msg.(type) {
case error:
combined = append(combined, err)
case string:
combined = append(combined, errors.New(err))
}
}
return errors.Join(combined...)
}
// Next executes the next handler in the middleware chain.
func (ctx *context) Next() error {
ctx.handlerCount++
return ctx.server.handlers[ctx.handlerCount](ctx)
}
// Redirect redirects the client to a different location
// with the specified status code.
func (ctx *context) Redirect(status int, location string) error {
ctx.response.SetStatus(status)
ctx.response.SetHeader("Location", location)
return nil
}
// Request returns the HTTP request.
func (ctx *context) Request() Request {
return &ctx.request
}
// Response returns the HTTP response.
func (ctx *context) Response() Response {
return &ctx.response
}
// Status sets the HTTP status of the response
// and returns the context for method chaining.
func (ctx *context) Status(status int) Context {
ctx.response.SetStatus(status)
return ctx
}
// String adds the given string to the response body.
func (ctx *context) String(body string) error {
ctx.response.body = append(ctx.response.body, body...)
return nil
}