85 lines
2.0 KiB
Go
Raw Permalink Normal View History

2023-07-09 21:24:24 +02:00
package router
// Router is a high-performance router.
2023-07-18 17:14:34 +02:00
type Router[T any] struct {
2023-07-09 21:24:24 +02:00
get Tree[T]
post Tree[T]
delete Tree[T]
put Tree[T]
patch Tree[T]
head Tree[T]
connect Tree[T]
trace Tree[T]
options Tree[T]
}
// New creates a new router containing trees for every HTTP method.
2023-07-18 17:14:34 +02:00
func New[T any]() *Router[T] {
2023-07-09 21:24:24 +02:00
return &Router[T]{}
}
// Add registers a new handler for the given method and path.
func (router *Router[T]) Add(method string, path string, handler T) {
tree := router.selectTree(method)
tree.Add(path, handler)
}
// Lookup finds the handler and parameters for the given route.
2024-03-14 23:26:59 +01:00
func (router *Router[T]) Lookup(method string, path string) (T, []Parameter) {
2023-07-09 21:24:24 +02:00
if method[0] == 'G' {
return router.get.Lookup(path)
}
tree := router.selectTree(method)
return tree.Lookup(path)
}
// LookupNoAlloc finds the handler and parameters for the given route without using any memory allocations.
func (router *Router[T]) LookupNoAlloc(method string, path string, addParameter func(string, string)) T {
if method[0] == 'G' {
return router.get.LookupNoAlloc(path, addParameter)
}
tree := router.selectTree(method)
return tree.LookupNoAlloc(path, addParameter)
}
2023-09-06 16:52:22 +02:00
// Map traverses all trees and calls the given function on every node.
func (router *Router[T]) Map(transform func(T) T) {
router.get.Map(transform)
router.post.Map(transform)
router.delete.Map(transform)
router.put.Map(transform)
router.patch.Map(transform)
router.head.Map(transform)
router.connect.Map(transform)
router.trace.Map(transform)
router.options.Map(transform)
2023-07-10 14:48:28 +02:00
}
2023-07-09 21:24:24 +02:00
// selectTree returns the tree by the given HTTP method.
func (router *Router[T]) selectTree(method string) *Tree[T] {
switch method {
case "GET":
return &router.get
case "POST":
return &router.post
case "DELETE":
return &router.delete
case "PUT":
return &router.put
case "PATCH":
return &router.patch
case "HEAD":
return &router.head
case "CONNECT":
return &router.connect
case "TRACE":
return &router.trace
case "OPTIONS":
return &router.options
default:
return nil
}
}