-
Notifications
You must be signed in to change notification settings - Fork 0
/
router.go
136 lines (117 loc) · 3.54 KB
/
router.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package poteto
import (
"errors"
"net/http"
"strings"
)
type Router interface {
add(method, path string, handler HandlerFunc) error
GET(path string, handler HandlerFunc) error
POST(path string, handler HandlerFunc) error
PUT(path string, handler HandlerFunc) error
PATCH(path string, handler HandlerFunc) error
DELETE(path string, handler HandlerFunc) error
HEAD(path string, handler HandlerFunc) error
OPTIONS(path string, handler HandlerFunc) error
TRACE(path string, handler HandlerFunc) error
CONNECT(path string, handler HandlerFunc) error
GetRoutesByMethod(method string) *route
}
// Each Router has TrieTreeRouting by method
type router struct {
routesGET Route
routesPOST Route
routesPUT Route
routesPATCH Route
routesDELETE Route
routesHEAD Route
routesOPTIONS Route
routesTRACE Route
routesCONNECT Route
}
func NewRouter() Router {
return &router{
routesGET: NewRoute(),
routesPOST: NewRoute(),
routesPUT: NewRoute(),
routesPATCH: NewRoute(),
routesDELETE: NewRoute(),
routesHEAD: NewRoute(),
routesOPTIONS: NewRoute(),
routesTRACE: NewRoute(),
routesCONNECT: NewRoute(),
}
}
func (r *router) add(method, path string, handler HandlerFunc) error {
routes := r.GetRoutesByMethod(method)
if routes == nil {
return errors.New("unexpected method error: " + method)
}
thisRoute, _ := routes.Search(path)
if thisRoute != nil {
if path == "/" {
thisRoute.handler = handler
return nil
}
return errors.New("[" + method + "] " + path + " is already used")
}
// "/users/" -> "/users"
// if just "/" -> handler set by above
path = strings.TrimSuffix(path, "/")
routes.Insert(path, handler)
return nil
}
// These are router Method
// Seems redundant, but you can register your own router with poteto
// And call it with `Poteto.GET()` etc.
func (r *router) GET(path string, handler HandlerFunc) error {
return r.add(http.MethodGet, path, handler)
}
func (r *router) POST(path string, handler HandlerFunc) error {
return r.add(http.MethodPost, path, handler)
}
func (r *router) PUT(path string, handler HandlerFunc) error {
return r.add(http.MethodPut, path, handler)
}
func (r *router) PATCH(path string, handler HandlerFunc) error {
return r.add(http.MethodPatch, path, handler)
}
func (r *router) DELETE(path string, handler HandlerFunc) error {
return r.add(http.MethodDelete, path, handler)
}
func (r *router) HEAD(path string, handler HandlerFunc) error {
return r.add(http.MethodHead, path, handler)
}
func (r *router) OPTIONS(path string, handler HandlerFunc) error {
return r.add(http.MethodOptions, path, handler)
}
func (r *router) TRACE(path string, handler HandlerFunc) error {
return r.add(http.MethodTrace, path, handler)
}
func (r *router) CONNECT(path string, handler HandlerFunc) error {
return r.add(http.MethodConnect, path, handler)
}
func (r *router) GetRoutesByMethod(method string) *route {
switch method {
case http.MethodGet:
return r.routesGET.(*route)
case http.MethodPost:
return r.routesPOST.(*route)
case http.MethodPut:
return r.routesPUT.(*route)
case http.MethodPatch:
return r.routesPATCH.(*route)
case http.MethodDelete:
return r.routesDELETE.(*route)
case http.MethodHead:
return r.routesHEAD.(*route)
case http.MethodOptions:
return r.routesOPTIONS.(*route)
case http.MethodTrace:
return r.routesTRACE.(*route)
case http.MethodConnect:
return r.routesCONNECT.(*route)
default:
return nil
}
}