func (context *Context) ParamString(key string, d ...string) string {
	if param, ok := context.Params[key]; ok {
		return param
	}
	if len(d) > 0 {
		return d[0]
	}
	return ""
}
ParamString Get param string field with the specific key.
package router
import (
	"fmt"
	"net/http"
	"strconv"
	"github.com/importcjj/trie-go"
)
const (
	MethodGet    = "GET"
	MethodPost   = "POST"
	MethodPut    = "PUT"
	MethodPatch  = "PATCH"
	MethodDelete = "DELETE"
)
type Router struct {
	trie     *trie.Trie
	handlers map[string]*Handler
}
func New() *Router {
	return &Router{
		trie: trie.New(),
	}
}
func (router *Router) Router(pattern string, handler HandlerInterface) {
	router.trie.Put(pattern, handler)
}
func (router *Router) Before(pattern string, midwares ...func(*Context)) {
	exist, node := router.trie.GetNode(pattern)
	if exist {
		if beforeHooks, ok := node.Data["_before_hooks"]; ok {
			hooks := beforeHooks.([]func(*Context))
			node.Data["_before_hooks"] = append(hooks, midwares...)
			return
		}
		node.Data["_before_hooks"] = midwares
		return
	}
}
func (router *Router) After(pattern string, midwares ...func(context *Context)) {
	exist, node := router.trie.GetNode(pattern)
	if exist {
		if afterHooks, ok := node.Data["_after_hooks"]; ok {
			hooks := afterHooks.([]func(*Context))
			node.Data["_after_hooks"] = append(hooks, midwares...)
			return
		}
		node.Data["_after_hooks"] = midwares
		return
	}
}
func (router *Router) Get(pattern string, handlefunc func(*Context)) {
	exist, node := router.trie.GetNode(pattern)
	var handler HandlerInterface
	if exist {
		h := node.Value
		handler = h.(HandlerInterface)
	} else {
		handler = NewHanlder()
	}
	handler.Get(handlefunc)
	router.trie.Put(pattern, handler)
}
func (router *Router) Post(pattern string, handlefunc func(*Context)) {
	exist, node := router.trie.GetNode(pattern)
	var handler HandlerInterface
	if exist {
		h := node.Value
		handler = h.(HandlerInterface)
	} else {
		handler = &Handler{}
	}
	handler.Post(handlefunc)
	router.trie.Put(pattern, handler)
}
func (router *Router) Put(pattern string, handlefunc func(*Context)) {
	exist, node := router.trie.GetNode(pattern)
	var handler HandlerInterface
	if exist {
		h := node.Value
		handler = h.(HandlerInterface)
	} else {
		handler = &Handler{}
	}
	handler.Put(handlefunc)
	router.trie.Put(pattern, handler)
}
func (router *Router) Patch(pattern string, handlefunc func(*Context)) {
	exist, node := router.trie.GetNode(pattern)
	var handler HandlerInterface
	if exist {
		h := node.Value
		handler = h.(HandlerInterface)
	} else {
		handler = &Handler{}
	}
	handler.Patch(handlefunc)
	router.trie.Put(pattern, handler)
}
func (router *Router) Delete(pattern string, handlefunc func(*Context)) {
	exist, node := router.trie.GetNode(pattern)
	var handler HandlerInterface
	if exist {
		h := node.Value
		handler = h.(HandlerInterface)
	} else {
		handler = &Handler{}
	}
	handler.Delete(handlefunc)
	router.trie.Put(pattern, handler)
}
type Handler struct {
	funcs    map[string]func(*Context)
	OnGet    func(context *Context)
	OnPost   func(context *Context)
	OnPut    func(context *Context)
	OnPatch  func(context *Context)
	OnDelete func(context *Context)
}
func NewHanlder() *Handler {
	return &Handler{
		funcs: make(map[string]func(*Context)),
	}
}
type HandlerInterface interface {
	Get(func(*Context))
	Post(func(*Context))
	Put(func(*Context))
	Patch(func(*Context))
	Delete(func(*Context))
	DoGet(*Context)
	DoPost(*Context)
	DoPut(*Context)
	DoPatch(*Context)
	DoDelete(*Context)
}
func (handler *Handler) Get(handleFunc func(*Context)) {
	handler.OnGet = handleFunc
}
func (handler *Handler) Post(handleFunc func(*Context)) {
	handler.OnPost = handleFunc
}
func (handler *Handler) Put(handleFunc func(*Context)) {
	handler.OnPut = handleFunc
}
func (handler *Handler) Patch(handleFunc func(*Context)) {
	handler.OnPatch = handleFunc
}
func (handler *Handler) Delete(handleFunc func(*Context)) {
	handler.OnDelete = handleFunc
}
func (handler *Handler) DoGet(context *Context) {
	if handler.OnGet == nil {
		status := http.StatusMethodNotAllowed
		text := http.StatusText(status)
		context.ResponseWriter.Write([]byte(text))
		context.ResponseWriter.WriteHeader(status)
		return
	}
	handler.OnGet(context)
}
func (handler *Handler) DoPost(context *Context) {
	if handler.OnPost == nil {
		status := http.StatusMethodNotAllowed
		text := http.StatusText(status)
		context.ResponseWriter.Write([]byte(text))
		context.ResponseWriter.WriteHeader(status)
		return
	}
	handler.OnPost(context)
}
func (handler *Handler) DoPut(context *Context) {
	if handler.OnPut == nil {
		status := http.StatusMethodNotAllowed
		text := http.StatusText(status)
		context.ResponseWriter.Write([]byte(text))
		context.ResponseWriter.WriteHeader(status)
		return
	}
	handler.OnPut(context)
}
func (handler *Handler) DoPatch(context *Context) {
	if handler.OnPatch == nil {
		status := http.StatusMethodNotAllowed
		text := http.StatusText(status)
		context.ResponseWriter.Write([]byte(text))
		context.ResponseWriter.WriteHeader(status)
		return
	}
	handler.OnPatch(context)
}
func (handler *Handler) DoDelete(context *Context) {
	if handler.OnDelete == nil {
		status := http.StatusMethodNotAllowed
		text := http.StatusText(status)
		context.ResponseWriter.Write([]byte(text))
		context.ResponseWriter.WriteHeader(status)
		return
	}
	handler.OnDelete(context)
}
func (router *Router) mapMidwares(context *Context, midwares ...func(*Context)) {
	for _, midware := range midwares {
		midware(context)
	}
}
func (router *Router) ServeDir(dirname string) {
	prefix := fmt.Sprintf("/%s", dirname)
	pattern := fmt.Sprintf("/%s/<filename:*>", dirname)
	fileserver := http.StripPrefix(prefix, http.FileServer(http.Dir(dirname)))
	router.Get(pattern, func(ctx *Context) {
		fileserver.ServeHTTP(ctx.ResponseWriter, ctx.Request)
	})
}
func (router *Router) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
	ok, result := router.trie.Match(r.RequestURI)
	if !ok {
		rw.Write([]byte(http.StatusText(http.StatusNotFound)))
		return
	}
	ctx := NewContent(rw, r)
	ctx.Params = result.Params
	h := result.Value
	handler := h.(HandlerInterface)
	for _, data := range result.ChainData {
		hooks := data["_before_hooks"]
		if hooks != nil {
			for _, hook := range hooks.([]func(*Context)) {
				hook(ctx)
			}
		}
	}
	switch r.Method {
	case MethodGet:
		handler.DoGet(ctx)
	case MethodPost:
		handler.DoPost(ctx)
	case MethodPatch:
		handler.DoPatch(ctx)
	case MethodPut:
		handler.DoPut(ctx)
	case MethodDelete:
		handler.DoDelete(ctx)
	default:
		status := http.StatusMethodNotAllowed
		text := http.StatusText(status)
		rw.Write([]byte(text))
		rw.WriteHeader(status)
	}
	for _, data := range result.ChainData {
		hooks := data["_after_hooks"]
		if hooks != nil {
			for _, hook := range hooks.([]func(*Context)) {
				hook(ctx)
			}
		}
	}
}
type Context struct {
	Params         map[string]string
	Data           map[string]interface{}
	ResponseWriter http.ResponseWriter
	Request        *http.Request
}
func NewContent(rw http.ResponseWriter, r *http.Request) *Context {
	return &Context{
		ResponseWriter: rw,
		Data:           make(map[string]interface{}),
		Request:        r,
	}
}
func (context *Context) WriteString(v string) {
	context.ResponseWriter.Write([]byte(v))
}