-
Notifications
You must be signed in to change notification settings - Fork 1
/
routergroup.go
101 lines (86 loc) · 2.48 KB
/
routergroup.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
package gotham
// IHandlers defines all routers which have handlers,
// and a unique name .
type IHandlers interface {
Handlers() HandlersChain
Name() string
}
// IRoutes defines all router handle interface.
type IRoutes interface {
Handle(string, ...HandlerFunc) IRoutes
Use(...HandlerFunc) IRoutes
}
// RouterGroup is used internally to configure router, a RouterGroup is associated with
// a prefix and an array of handlers (middleware).
type RouterGroup struct {
handlers HandlersChain
name string
router *Router
}
// Use adds middleware to the group, see example code in GitHub.
func (group *RouterGroup) Use(middlewares ...HandlerFunc) IRoutes {
group.handlers = append(group.handlers, middlewares...)
return group
}
// Handle
func (group *RouterGroup) Handle(name string, handlers ...HandlerFunc) IRoutes {
var pn *pnode = group.router.nodes.get(name)
if pn == nil {
pn = &pnode{name: name}
group.router.nodes = append(group.router.nodes, pn)
}
pn.addGroup(group.router)
pn.addGroup(group)
pn.rebuildHandlers(handlers...)
return group
}
// Handle registers a new request handle and middleware with the given path and method.
// The last handler should be the real handler, the other ones should be middleware that can and should be shared among different routes.
// See the example code in GitHub.
func (group *RouterGroup) Handlers() HandlersChain {
return group.handlers
}
func (group *RouterGroup) Name() string {
return group.name
}
type pnodes []*pnode
type pnode struct {
name string
groups []IHandlers
phandlers HandlersChain
handlers HandlersChain
}
func (pn *pnode) combineHandlers(handlers HandlersChain) HandlersChain {
finalSize := len(pn.handlers) + len(handlers)
if finalSize >= int(abortIndex) {
panic("too many handlers")
}
mergedHandlers := make(HandlersChain, finalSize)
copy(mergedHandlers, pn.handlers)
copy(mergedHandlers[len(pn.handlers):], handlers)
return mergedHandlers
}
func (pn *pnode) addGroup(group IHandlers) {
for _, g := range pn.groups {
if g.Name() == group.Name() {
return
}
}
pn.groups = append(pn.groups, group)
}
func (pn *pnode) rebuildHandlers(handlers ...HandlerFunc) {
pn.phandlers = append(pn.phandlers, handlers...)
pn.handlers = pn.handlers[:0]
for _, group := range pn.groups {
pn.handlers = pn.combineHandlers(group.Handlers())
}
pn.handlers = pn.combineHandlers(pn.phandlers)
}
func (nodes pnodes) get(name string) *pnode {
for _, n := range nodes {
if n.name == name {
return n
}
}
return nil
}