74 lines
1.9 KiB
Go
74 lines
1.9 KiB
Go
package routes
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"maps"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/a-h/templ"
|
|
)
|
|
|
|
func render(component func(context.Context) templ.Component) func(http.ResponseWriter, *http.Request) {
|
|
return func(writer http.ResponseWriter, req *http.Request) {
|
|
err := component(req.Context()).Render(req.Context(), writer)
|
|
if err != nil {
|
|
http.Error(writer, fmt.Sprintf("can't render component: %s", err), http.StatusInternalServerError)
|
|
}
|
|
}
|
|
}
|
|
|
|
func normalizePath(pathSegments ...string) string {
|
|
normalized := make([]string, len(pathSegments))
|
|
|
|
for i, segment := range pathSegments {
|
|
normalized[i] = strings.Trim(segment, "/")
|
|
}
|
|
|
|
return "/" + strings.TrimPrefix(strings.Join(normalized, "/"), "/")
|
|
}
|
|
|
|
func routesToMap(rootPath string, route *Route) RoutesMap {
|
|
routesMap := make(RoutesMap, 0)
|
|
|
|
optionsHandler := route.Options
|
|
if optionsHandler == nil {
|
|
allowed := []string{}
|
|
if route.Get != nil {
|
|
allowed = append(allowed, http.MethodGet)
|
|
}
|
|
if route.Post != nil {
|
|
allowed = append(allowed, http.MethodPost)
|
|
}
|
|
if route.Put != nil {
|
|
allowed = append(allowed, http.MethodPut)
|
|
}
|
|
if route.Delete != nil {
|
|
allowed = append(allowed, http.MethodDelete)
|
|
}
|
|
allowed = append(allowed, http.MethodOptions)
|
|
|
|
allowedString := strings.Join(allowed, ", ")
|
|
optionsHandler = func(writer http.ResponseWriter, req *http.Request) {
|
|
writer.Header().Set("Allow", allowedString)
|
|
writer.WriteHeader(http.StatusNoContent)
|
|
}
|
|
}
|
|
|
|
currentPath := normalizePath(rootPath, route.Path)
|
|
routesMap[currentPath] = map[string]func(http.ResponseWriter, *http.Request){
|
|
http.MethodGet: route.Get,
|
|
http.MethodPost: route.Post,
|
|
http.MethodPut: route.Put,
|
|
http.MethodDelete: route.Delete,
|
|
http.MethodOptions: optionsHandler,
|
|
}
|
|
|
|
for _, sub := range route.SubRoutes {
|
|
maps.Copy(routesMap, routesToMap(currentPath, sub))
|
|
}
|
|
|
|
return routesMap
|
|
}
|