93 lines
1.8 KiB
Go
93 lines
1.8 KiB
Go
package joist
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"net/http"
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
jerr "git.markbailey.dev/cerbervs/joist/internal/errors"
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
type RouteInfo struct {
|
|
Method string
|
|
Name string
|
|
Path string
|
|
Description string
|
|
Title string
|
|
}
|
|
|
|
func NewRouteInfo(method, path, description, title string) (RouteInfo, error) {
|
|
name, err := convertRouteToRouteName(path)
|
|
if err != nil {
|
|
return RouteInfo{}, err
|
|
}
|
|
|
|
return RouteInfo{
|
|
Method: method,
|
|
Name: name,
|
|
Path: path,
|
|
Description: description,
|
|
Title: title,
|
|
}, nil
|
|
}
|
|
|
|
type routeInfoKey struct{}
|
|
|
|
type Router struct {
|
|
chi.Mux
|
|
cache RouteCacher
|
|
cacheTTL time.Duration
|
|
}
|
|
|
|
func NewRouter() Router {
|
|
ttl := 8 * time.Hour
|
|
|
|
cache, err := NewRouteCacheService(WithTTL(ttl))
|
|
if err != nil {
|
|
log.Fatal(jerr.Wrap(err, jerr.ErrRouterNotCreated))
|
|
}
|
|
|
|
return Router{cache: cache, cacheTTL: ttl}
|
|
}
|
|
|
|
func (ro *Router) WithRouteInfo(ri RouteInfo, h HandlerFn) http.HandlerFunc {
|
|
ro.cache.AddRouteInfo(ri)
|
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
ctx := context.WithValue(r.Context(), routeInfoKey{}, ri)
|
|
h.ServeHTTP(w, r.WithContext(ctx))
|
|
}
|
|
}
|
|
|
|
// TODO: move to base handler when it's implemented
|
|
func GetRouteInfo(r *http.Request) (RouteInfo, bool) {
|
|
info, ok := r.Context().Value(routeInfoKey{}).(RouteInfo)
|
|
return info, ok
|
|
}
|
|
|
|
func convertRouteToRouteName(route string) (string, error) {
|
|
name := "app"
|
|
if route == "/" {
|
|
return name + ".home", nil
|
|
}
|
|
|
|
route = strings.ReplaceAll(route, "/", ".")
|
|
route = strings.ReplaceAll(route, "-", "_")
|
|
|
|
paramRegex := regexp.MustCompile(`\.{[^}]*}`)
|
|
params := paramRegex.FindAllString(route, -1)
|
|
route = paramRegex.ReplaceAllString(route, "")
|
|
|
|
if len(params) > 0 {
|
|
route += ".params"
|
|
}
|
|
|
|
name += strings.TrimRight(route, ".")
|
|
|
|
return name, nil
|
|
}
|