sux/sux.go

129 lines
2.6 KiB
Go
Raw Permalink Normal View History

2021-10-31 09:03:21 +01:00
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
}