-
Notifications
You must be signed in to change notification settings - Fork 1
/
router.go
88 lines (72 loc) · 1.74 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
package minimalrouter
import "strings"
func New() *Router {
return &Router{children: make(map[string]*Router)}
}
// Represents both the Router and each node
type Router struct {
children map[string]*Router
varName string
handler interface{}
}
func (this *Router) Get(path string, h interface{}) {
this.Add("GET", path, h)
}
func (this *Router) Post(path string, h interface{}) {
this.Add("POST", path, h)
}
func (this *Router) Put(path string, h interface{}) {
this.Add("PUT", path, h)
}
func (this *Router) Delete(path string, h interface{}) {
this.Add("DELETE", path, h)
}
func (this *Router) Add(method, path string, h interface{}) {
parts := []string{method}
path = strings.Trim(path, "/")
if len(path) > 0 {
parts = append(parts, strings.Split(path, "/")...)
}
node := this
for _, p := range parts {
if p[0] == ':' && len(p) > 2 {
varName := p[1:]
p = ":"
if node.varName == "" {
node.varName = varName
} else if node.varName != varName {
panic("conflict while adding " + path + "; parameter conflicts with :" + node.varName)
}
}
n, ok := node.children[p]
if !ok {
node.children[p] = New()
n = node.children[p]
}
node = n
}
if node.handler != nil {
panic("duplicate path: " + path)
}
node.handler = h
}
func (this *Router) Match(method, path string) (interface{}, map[string]string) {
parts := []string{method}
path = strings.Trim(path, "/")
if len(path) > 0 {
parts = append(parts, strings.Split(path, "/")...)
}
params := make(map[string]string)
node := this
for _, p := range parts {
n, ok := node.children[p]
if !ok && node.varName != "" {
n = node.children[":"]
params[node.varName] = p
} else if !ok {
return nil, nil
}
node = n
}
return node.handler, params
}