package goblocks import ( "net/http" "slices" ) type Middleware func(http.Handler) http.Handler type Router struct { globalChain []Middleware routeChain []Middleware isSub bool *http.ServeMux } func newRouter() *Router { return &Router{ServeMux: http.NewServeMux()} } func (r *Router) Use(mw ...Middleware) { if r.isSub { r.routeChain = append(r.routeChain, mw...) } else { r.globalChain = append(r.globalChain, mw...) } } func (r *Router) Group(fn func(r *Router)) { sub := &Router{ ServeMux: r.ServeMux, routeChain: slices.Clone(r.routeChain), isSub: true, } fn(sub) } func (r *Router) HandleFunc(pattern string, h http.HandlerFunc) { r.Handle(pattern, h) } func (r *Router) Handle(pattern string, h http.Handler) { chain := slices.Clone(r.routeChain) slices.Reverse(chain) for _, mw := range chain { h = mw(h) } r.ServeMux.Handle(pattern, h) } func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { h := http.Handler(r.ServeMux) chain := slices.Clone(r.globalChain) slices.Reverse(chain) for _, mw := range chain { h = mw(h) } h.ServeHTTP(w, req) }