From a555355d69a4fe9cd01d8bea86ce5b057cd1cd66 Mon Sep 17 00:00:00 2001 From: Eltrac Date: Wed, 26 Nov 2025 09:54:49 +0800 Subject: feat: implement minimal router --- context.go | 20 ++++++++++++++++++++ router.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/context.go b/context.go index aa10769..fbb6a1e 100644 --- a/context.go +++ b/context.go @@ -1 +1,21 @@ package growel + +import ( + "net/http" +) + +type Context struct { + W http.ResponseWriter + R http.Request + Params map[string]string +} + +type Handler func(c *Context) + +func (h Handler) ServeHTTP(w http.ResponseWriter, r http.Request) { + h(&Context{ + W: w, + R: r, + Params: make(map[string]string), + }) +} diff --git a/router.go b/router.go index aa10769..5428701 100644 --- a/router.go +++ b/router.go @@ -1 +1,60 @@ package growel + +import ( + "strings" +) + +type route struct { + method string + parts []string + handler Handler +} + +type Router struct { + routes []route +} + +func NewRouter() *Router { + return &Router{} +} + +func (r *Router) Add(method, path string, h Handler) { + parts := strings.Split(path, "/") + r.routes = append(r.routes, route{method, parts, h}) +} + +func (r *Router) Find(method, path string) (Handler, map[string]string) { + parts := strings.Split(path, "/") + + for _, rt := range r.routes { + // match HTTP method + if rt.method != method { + continue + } + + // match path part number + if len(rt.parts) != len(parts) { + continue + } + + // compare each segment + params := make(map[string]string) + matched := true + for i, seg := range rt.parts { + // parse dynamic parameter + if strings.HasPrefix(seg, ":") { + params[seg[1:]] = parts[i] + } + + // static mismatch + if seg != parts[i] { + matched = false + break + } + } + if matched { + return rt.handler, params + } + } + return nil, nil +} -- cgit v1.2.3