@@ -2,57 +2,55 @@ package routing
22
33import (
44 "github.com/valyala/fasthttp"
5+ "strings"
56)
67
78type Handler func (ctx * Context ) error
89
9- type Router struct {
10- routes map [string ]* route
11- stores map [string ]RouteStore
12- notFoundHandler Handler
13- maxParams int
10+ type Route struct {
11+ Path string
12+ ParamNames []string
13+ Handlers []Handler
1414}
1515
16- func CombineHandlers (handlers ... Handler ) Handler {
17- return func (ctx * Context ) error {
18- for _ , handler := range handlers {
19- if err := handler (ctx ); err != nil {
20- return err
21- }
22- }
23- return nil
24- }
16+ type Router struct {
17+ routes map [string ][]* Route
18+ notFoundHandler Handler
2519}
2620
2721func New () * Router {
2822 return & Router {
29- routes : make (map [string ]* route ),
30- stores : make (map [string ]RouteStore ),
23+ routes : make (map [string ][]* Route ),
3124 }
3225}
3326
3427func (r * Router ) add (method , path string , handlers []Handler ) {
35- s := r .stores [method ]
36- if s == nil {
37- s = newStore ()
38- r .stores [method ] = s
28+ route := & Route {
29+ Path : path ,
30+ Handlers : handlers ,
3931 }
40- if n := s .Add (path , handlers ); n > r .maxParams {
41- r .maxParams = n
32+
33+ parts := strings .Split (path , "/" )
34+ for _ , part := range parts {
35+ if strings .HasPrefix (part , ":" ) {
36+ route .ParamNames = append (route .ParamNames , strings .TrimPrefix (part , ":" ))
37+ }
4238 }
43- r .routes [method + path ] = & route {method , path , CombineHandlers (handlers ... )}
39+ route .Path = strings .Join (parts , "/" )
40+
41+ r .routes [method ] = append (r .routes [method ], route )
4442}
4543
4644func (r * Router ) find (method , path string ) []Handler {
47- s := r .stores [method ]
48- if s == nil {
49- return [] Handler {}
50- }
51- handlers , ok := s . Get ( path ).([] Handler )
52- if ! ok {
53- return [] Handler { }
45+ routes := r .routes [method ]
46+ for _ , route := range routes {
47+ if matches , params := route . match ( path ); matches {
48+ c := NewContext ( nil , nil )
49+ c . params = params
50+ return route . Handlers
51+ }
5452 }
55- return handlers
53+ return nil
5654}
5755
5856func RouterHandler (router * Router ) func (ctx * fasthttp.RequestCtx ) {
@@ -64,7 +62,24 @@ func RouterHandler(router *Router) func(ctx *fasthttp.RequestCtx) {
6462 ctx .Error ("Not found" , fasthttp .StatusNotFound )
6563 return
6664 }
67- c := NewContext (ctx )
65+
66+ params := make (map [string ]string )
67+ for _ , route := range router .routes [method ] {
68+ if matches , params := route .match (path ); matches {
69+ c := NewContext (ctx , nil ).WithParams (params )
70+ for _ , h := range handlers {
71+ err := h (c )
72+ if err != nil {
73+ ctx .Error (err .Error (), fasthttp .StatusInternalServerError )
74+ return
75+ }
76+ }
77+ return
78+ }
79+ }
80+
81+ c := NewContext (ctx , params )
82+
6883 for _ , h := range handlers {
6984 err := h (c )
7085 if err != nil {
@@ -74,3 +89,24 @@ func RouterHandler(router *Router) func(ctx *fasthttp.RequestCtx) {
7489 }
7590 }
7691}
92+
93+ func (r * Route ) match (path string ) (bool , map [string ]string ) {
94+ parts := strings .Split (path , "/" )
95+ routeParts := strings .Split (r .Path , "/" )
96+
97+ if len (parts ) != len (routeParts ) {
98+ return false , nil
99+ }
100+
101+ params := make (map [string ]string )
102+ for i , part := range routeParts {
103+ if strings .HasPrefix (part , ":" ) {
104+ paramName := strings .TrimPrefix (part , ":" )
105+ params [paramName ] = parts [i ]
106+ } else if part != parts [i ] {
107+ return false , nil
108+ }
109+ }
110+
111+ return true , params
112+ }
0 commit comments