initial
This commit is contained in:
128
sux.go
Normal file
128
sux.go
Normal file
@@ -0,0 +1,128 @@
|
||||
package sux
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
nomatch uint8 = iota
|
||||
static
|
||||
)
|
||||
|
||||
type (
|
||||
node struct {
|
||||
term byte
|
||||
ntype uint8
|
||||
handler http.HandlerFunc
|
||||
child []*node
|
||||
}
|
||||
Router struct {
|
||||
route map[string]*node
|
||||
}
|
||||
)
|
||||
|
||||
var root *Router
|
||||
|
||||
func makenode(term byte) *node {
|
||||
return &node{
|
||||
term: term,
|
||||
child: make([]*node, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (n *node) addchild(term byte) *node {
|
||||
if fn := n.findchild(term); fn == nil {
|
||||
nn := makenode(term)
|
||||
n.child = append(n.child, nn)
|
||||
return nn
|
||||
} else {
|
||||
return fn
|
||||
}
|
||||
}
|
||||
|
||||
func (n *node) maketree(word []byte, handler http.HandlerFunc) {
|
||||
m := n
|
||||
for i, l := 1, len(word); i < l; i++ {
|
||||
m = m.addchild(word[i])
|
||||
}
|
||||
m.ntype = static
|
||||
m.handler = handler
|
||||
}
|
||||
|
||||
func (n *node) findchild(term byte) *node {
|
||||
for _, v := range n.child {
|
||||
if v.term == term {
|
||||
return v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *node) find(word string) *node {
|
||||
ss := []byte(word)
|
||||
m := n
|
||||
for i, l := 1, len(ss); i < l; i++ {
|
||||
m = m.findchild(ss[i])
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (n *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if m, exists := n.route[r.Method]; exists {
|
||||
m = m.find(r.URL.Path)
|
||||
if m == nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
if m.ntype == nomatch {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
m.handler(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Router) GET(path string, handler http.HandlerFunc) *Router {
|
||||
n.route["GET"].maketree([]byte(path), handler)
|
||||
return n
|
||||
}
|
||||
func (n *Router) POST(path string, handler http.HandlerFunc) *Router {
|
||||
n.route["POST"].maketree([]byte(path), handler)
|
||||
return n
|
||||
}
|
||||
func (n *Router) PUT(path string, handler http.HandlerFunc) *Router {
|
||||
n.route["PUT"].maketree([]byte(path), handler)
|
||||
return n
|
||||
}
|
||||
func (n *Router) PATCH(path string, handler http.HandlerFunc) *Router {
|
||||
n.route["PATCH"].maketree([]byte(path), handler)
|
||||
return n
|
||||
}
|
||||
func (n *Router) DELETE(path string, handler http.HandlerFunc) *Router {
|
||||
n.route["DELETE"].maketree([]byte(path), handler)
|
||||
return n
|
||||
}
|
||||
func (n *Router) OPTIONS(path string, handler http.HandlerFunc) *Router {
|
||||
n.route["OPTIONS"].maketree([]byte(path), handler)
|
||||
return n
|
||||
}
|
||||
func (n *Router) HEAD(path string, handler http.HandlerFunc) *Router {
|
||||
n.route["HEAD"].maketree([]byte(path), handler)
|
||||
return n
|
||||
}
|
||||
|
||||
func New() *Router {
|
||||
root = &Router{route: make(map[string]*node)}
|
||||
root.route["GET"] = makenode([]byte("/")[0])
|
||||
root.route["POST"] = makenode([]byte("/")[0])
|
||||
root.route["PUT"] = makenode([]byte("/")[0])
|
||||
root.route["PATCH"] = makenode([]byte("/")[0])
|
||||
root.route["DELETE"] = makenode([]byte("/")[0])
|
||||
root.route["OPTIONS"] = makenode([]byte("/")[0])
|
||||
root.route["HEAD"] = makenode([]byte("/")[0])
|
||||
return root
|
||||
}
|
||||
Reference in New Issue
Block a user