From 834de42a3fd5b68c859f9585fcc14e9710ab1472 Mon Sep 17 00:00:00 2001 From: some Date: Tue, 8 Oct 2024 18:58:08 -0400 Subject: [PATCH] Add Router --- router.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 router.go diff --git a/router.go b/router.go new file mode 100644 index 0000000..0b29fab --- /dev/null +++ b/router.go @@ -0,0 +1,67 @@ +package router + +import ( + "fmt" + "net/http" + "strings" +) + +type Route struct { + pattern string + required bool +} + +type Router struct { + *http.ServeMux + routes map[Route]*server +} + +func NewRouter(mux *http.ServeMux, requiredRoutes []string) (ro *Router) { + if mux == nil { + mux = http.NewServeMux() + } + ro = &Router{ + ServeMux: mux, + routes: make(map[Route]*server), + } + for _, pattern := range requiredRoutes { + ro.routes[Route{pattern: pattern, required: true}] = &server{} + } + return +} + +func (ro *Router) Register(pattern string, server *server) (err error) { + if !strings.HasPrefix(pattern, "/") { + return fmt.Errorf("missing preceding slash in pattern (%s)", pattern) + } + if server == nil { + return fmt.Errorf("server must be set in register") + } + srv, required := ro.routes[Route{pattern: pattern, required: true}] + if !required { + srv, _ = ro.routes[Route{pattern: pattern, required: false}] + } + if srv != nil { + return fmt.Errorf("too many routes for same pattern (%s)", pattern) + } + srv = server + ro.ServeMux.Handle(string(pattern), srv) + return +} + +func (ro *Router) Validate() (err error) { + for route, server := range ro.routes { + if route.required && server == nil { + err = fmt.Errorf("missing required route for pattern (%s)", route.pattern) + return + } + } + return +} + +func (ro *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if err := ro.Validate(); err != nil { + panic(err) + } + ro.ServeMux.ServeHTTP(w, r) +}