2026-04-01 21:23:28 +00:00
|
|
|
package resource
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2026-04-01 22:01:31 +00:00
|
|
|
"net/http"
|
2026-04-01 21:23:28 +00:00
|
|
|
"strconv"
|
|
|
|
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
|
"github.com/gorilla/mux"
|
2026-04-01 22:01:31 +00:00
|
|
|
"github.com/rs/zerolog/log"
|
2026-04-01 21:23:28 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type router struct {
|
|
|
|
|
router *mux.Router
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewRouter(r *mux.Router) *router {
|
|
|
|
|
return &router{
|
|
|
|
|
router: r,
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-04-20 16:21:08 +00:00
|
|
|
func (r *router) IDFromURI(route string, uri string) (*int, error) {
|
|
|
|
|
var match mux.RouteMatch
|
|
|
|
|
req, _ := http.NewRequest("GET", uri, nil)
|
|
|
|
|
if !r.router.Match(req, &match) {
|
|
|
|
|
return nil, fmt.Errorf("URI does not match any known route: %s", uri)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
route_name := match.Route.GetName()
|
|
|
|
|
if route_name != route {
|
|
|
|
|
return nil, fmt.Errorf("URI is not for the correct resource '%s', but for '%s'", route, route_name)
|
|
|
|
|
}
|
|
|
|
|
vars := match.Vars
|
|
|
|
|
id_str, ok := vars["id"]
|
|
|
|
|
if !ok {
|
|
|
|
|
entry := log.Debug()
|
|
|
|
|
for k, v := range vars {
|
|
|
|
|
entry = entry.Str(k, v)
|
|
|
|
|
}
|
|
|
|
|
entry.Msg("current URI values")
|
|
|
|
|
return nil, fmt.Errorf("No id found in URI %s", uri)
|
|
|
|
|
}
|
|
|
|
|
id, err := strconv.Atoi(id_str)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("parse id: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return &id, nil
|
|
|
|
|
|
|
|
|
|
}
|
2026-04-01 22:01:31 +00:00
|
|
|
func (r *router) UUIDFromURI(route string, uri string) (*uuid.UUID, error) {
|
|
|
|
|
var match mux.RouteMatch
|
|
|
|
|
req, _ := http.NewRequest("GET", uri, nil)
|
|
|
|
|
if !r.router.Match(req, &match) {
|
|
|
|
|
return nil, fmt.Errorf("URI does not match any known route: %s", uri)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
route_name := match.Route.GetName()
|
|
|
|
|
if route_name != route {
|
|
|
|
|
return nil, fmt.Errorf("URI is not for the correct resource '%s', but for '%s'", route, route_name)
|
|
|
|
|
}
|
|
|
|
|
vars := match.Vars
|
|
|
|
|
uuid_str, ok := vars["uuid"]
|
|
|
|
|
if !ok {
|
|
|
|
|
entry := log.Debug()
|
|
|
|
|
for k, v := range vars {
|
|
|
|
|
entry = entry.Str(k, v)
|
|
|
|
|
}
|
|
|
|
|
entry.Msg("current URI values")
|
|
|
|
|
return nil, fmt.Errorf("No uuid found in URI %s", uri)
|
|
|
|
|
}
|
|
|
|
|
uid, err := uuid.Parse(uuid_str)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("parse uuid: %w", err)
|
|
|
|
|
}
|
|
|
|
|
return &uid, nil
|
|
|
|
|
}
|
2026-04-01 21:23:28 +00:00
|
|
|
func (r *router) IDToURI(route string, id int) (string, error) {
|
|
|
|
|
i := strconv.FormatInt(int64(id), 10)
|
2026-04-08 17:49:32 +00:00
|
|
|
return r.IDStrToURI(route, i)
|
|
|
|
|
}
|
|
|
|
|
func (r *router) IDStrToURI(route string, id string) (string, error) {
|
2026-04-01 21:23:28 +00:00
|
|
|
handler := r.router.Get(route)
|
|
|
|
|
if handler == nil {
|
|
|
|
|
return "", fmt.Errorf("nil handler '%s'", route)
|
|
|
|
|
}
|
2026-04-08 17:49:32 +00:00
|
|
|
uri, err := handler.URL("id", id)
|
2026-04-01 21:23:28 +00:00
|
|
|
if err != nil {
|
|
|
|
|
return "", fmt.Errorf("build uri: %w", err)
|
|
|
|
|
}
|
2026-04-02 01:18:25 +00:00
|
|
|
uri.Scheme = "https"
|
2026-04-01 21:23:28 +00:00
|
|
|
return uri.String(), nil
|
|
|
|
|
}
|
2026-04-03 18:17:19 +00:00
|
|
|
func (r *router) SlugToURI(route string, slug string) (string, error) {
|
|
|
|
|
handler := r.router.Get(route)
|
|
|
|
|
if handler == nil {
|
|
|
|
|
return "", fmt.Errorf("nil handler '%s'", route)
|
|
|
|
|
}
|
|
|
|
|
uri, err := handler.URL("slug", slug)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", fmt.Errorf("build uri: %w", err)
|
|
|
|
|
}
|
|
|
|
|
uri.Scheme = "https"
|
|
|
|
|
return uri.String(), nil
|
|
|
|
|
}
|
2026-04-01 21:23:28 +00:00
|
|
|
|
|
|
|
|
func (r *router) UUIDToURI(route string, u *uuid.UUID) (*string, error) {
|
|
|
|
|
if u == nil {
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
handler := r.router.Get(route)
|
|
|
|
|
if handler == nil {
|
|
|
|
|
return nil, fmt.Errorf("nil handler '%s'", route)
|
|
|
|
|
}
|
|
|
|
|
uri, err := handler.URL("uuid", u.String())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("build uri: %w", err)
|
|
|
|
|
}
|
2026-04-02 01:18:25 +00:00
|
|
|
uri.Scheme = "https"
|
2026-04-01 21:23:28 +00:00
|
|
|
result := uri.String()
|
|
|
|
|
return &result, nil
|
|
|
|
|
}
|