cerrado @ f5c307668c7fa3c367defc6e924d7c1e00303c16

 1package ext
 2
 3import (
 4	"errors"
 5	"fmt"
 6	"net/http"
 7
 8	"git.gabrielgio.me/cerrado/pkg/service"
 9	"git.gabrielgio.me/cerrado/templates"
10)
11
12type (
13	Router struct {
14		middlewares []Middleware
15		router      *http.ServeMux
16	}
17	Middleware          func(next http.HandlerFunc) http.HandlerFunc
18	ErrorRequestHandler func(w http.ResponseWriter, r *http.Request) error
19)
20
21func NewRouter() *Router {
22	return &Router{
23		router: http.NewServeMux(),
24	}
25}
26
27func (r *Router) Handler() http.Handler {
28	return r.router
29}
30
31func (r *Router) AddMiddleware(middleware Middleware) {
32	r.middlewares = append(r.middlewares, middleware)
33}
34
35func wrapError(next ErrorRequestHandler) http.HandlerFunc {
36	return func(w http.ResponseWriter, r *http.Request) {
37		if err := next(w, r); err != nil {
38			if errors.Is(err, service.ErrRepositoryNotFound) {
39				NotFound(w, r)
40			} else {
41				InternalServerError(r, w, err)
42			}
43		}
44	}
45}
46
47func (r *Router) run(next ErrorRequestHandler) http.HandlerFunc {
48	return func(w http.ResponseWriter, re *http.Request) {
49		req := wrapError(next)
50		for _, r := range r.middlewares {
51			req = r(req)
52		}
53		req(w, re)
54	}
55}
56
57func (r *Router) HandleFunc(path string, handler ErrorRequestHandler) {
58	r.router.HandleFunc(path, r.run(handler))
59}
60
61func NotFound(w http.ResponseWriter, r *http.Request) {
62	w.WriteHeader(http.StatusNotFound)
63	templates.WritePageTemplate(w, &templates.ErrorPage{
64		Message: "Not Found",
65	}, r.Context())
66}
67
68func Redirect(w http.ResponseWriter, location string) {
69	w.Header().Add("location", location)
70	w.WriteHeader(http.StatusTemporaryRedirect)
71}
72
73func InternalServerError(r *http.Request, w http.ResponseWriter, err error) {
74	w.WriteHeader(http.StatusInternalServerError)
75	templates.WritePageTemplate(w, &templates.ErrorPage{
76		Message: fmt.Sprintf("Internal Server Error:\n%s", err.Error()),
77	}, r.Context())
78}