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
|
package mooh
import (
"regexp"
"strings"
)
type fn map[string]func(*Request) (Response, error)
type Route struct {
Path string
Executors fn
Components []string
RequiredNamedComponents map[string]bool
OptionalNamedComponents map[string]bool
Length int
}
type Match struct {
Path string
Route *Route
Mapping map[string]string
Method string
}
var componentIsVariable = regexp.MustCompile("^:")
var namedComponentsRegex = regexp.MustCompile("^:(.*)$")
func (self *Route) Match(request Request) *Match {
methodMatch := false
for m, _ := range self.Executors {
if m == request.Method {
methodMatch = true
}
}
if methodMatch == false {
return nil
}
components := strings.Split(request.Request.URL.Path, "/")
if len(components) < self.Length {
return nil
}
mapping := map[string]string{}
for i, c := range self.Components {
p := components[i]
if componentIsVariable.MatchString(c) == true {
mapping[c] = p
} else {
if p != c {
return nil
}
}
}
match := &Match{
Path: request.Request.URL.Path,
Route: self,
Mapping: mapping,
Method: request.Method,
}
return match
}
func (self *Route) Execute(request *Request) (Response, error) {
code := self.Executors[request.Method]
return code(request)
}
func MakeRoute(path string, method string, code func(*Request) (Response, error)) Route {
components := []string{}
for _, c := range strings.Split(path, "/") {
if c != "" {
components = append(components, c)
}
}
namedComponents := getNamedComponents(components)
exec := fn{method: code}
route := Route{
Path: path,
Executors: exec,
Components: components,
RequiredNamedComponents: namedComponents,
Length: len(components),
}
return route
}
func getNamedComponents(components []string) map[string]bool {
namedComponents := map[string]bool{}
for _, c := range components {
if namedComponentsRegex.MatchString(c) == true {
namedComponents[c] = true
}
}
return namedComponents
}
|