...
1 package denco
2
3 import (
4 "net/http"
5 )
6
7
8 type Mux struct{}
9
10
11 func NewMux() *Mux {
12 return &Mux{}
13 }
14
15
16 func (m *Mux) GET(path string, handler HandlerFunc) Handler {
17 return m.Handler("GET", path, handler)
18 }
19
20
21 func (m *Mux) POST(path string, handler HandlerFunc) Handler {
22 return m.Handler("POST", path, handler)
23 }
24
25
26 func (m *Mux) PUT(path string, handler HandlerFunc) Handler {
27 return m.Handler("PUT", path, handler)
28 }
29
30
31 func (m *Mux) HEAD(path string, handler HandlerFunc) Handler {
32 return m.Handler("HEAD", path, handler)
33 }
34
35
36 func (m *Mux) Handler(method, path string, handler HandlerFunc) Handler {
37 return Handler{
38 Method: method,
39 Path: path,
40 Func: handler,
41 }
42 }
43
44
45 func (m *Mux) Build(handlers []Handler) (http.Handler, error) {
46 recordMap := make(map[string][]Record)
47 for _, h := range handlers {
48 recordMap[h.Method] = append(recordMap[h.Method], NewRecord(h.Path, h.Func))
49 }
50 mux := newServeMux()
51 for m, records := range recordMap {
52 router := New()
53 if err := router.Build(records); err != nil {
54 return nil, err
55 }
56 mux.routers[m] = router
57 }
58 return mux, nil
59 }
60
61
62 type Handler struct {
63
64 Method string
65
66
67 Path string
68
69
70 Func HandlerFunc
71 }
72
73
74 type HandlerFunc func(w http.ResponseWriter, r *http.Request, params Params)
75
76 type serveMux struct {
77 routers map[string]*Router
78 }
79
80 func newServeMux() *serveMux {
81 return &serveMux{
82 routers: make(map[string]*Router),
83 }
84 }
85
86
87 func (mux *serveMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
88 handler, params := mux.handler(r.Method, r.URL.Path)
89 handler(w, r, params)
90 }
91
92 func (mux *serveMux) handler(method, path string) (HandlerFunc, []Param) {
93 if router, found := mux.routers[method]; found {
94 if handler, params, found := router.Lookup(path); found {
95 return handler.(HandlerFunc), params
96 }
97 }
98 return NotFound, nil
99 }
100
101
102
103
104 var NotFound = func(w http.ResponseWriter, r *http.Request, _ Params) {
105 http.NotFound(w, r)
106 }
107
View as plain text