func (r *Route) Route(path string) *Route {
	if path[0] != '/' {
		path = "/" + path
	}
	if path != "/" {
		path = strings.TrimRight(path, "/")
	}
	if r.pattern != "" {
		path = r.pattern + path
	}
	pathParts := strings.Split(path, "/")
	if path == "/" {
		pathParts = pathParts[1:]
	}
	return r.create(pathParts, r.fullPath)
}
Route walks down the route tree following pattern and returns either a new or previously
existing node that represents that specific path.
package powermux
import (
	"net/http"
	"net/url"
	"sort"
	"strings"
	"sync"
)
const (
	methodAny = "ANY"
	notFound  = "NOT_FOUND"
)
type childList []*Route
func (l childList) Len() int {
	return len(l)
}
func (l childList) Less(i, j int) bool {
	return l[i].pattern < l[j].pattern
}
func (l childList) Swap(i, j int) {
	l[i], l[j] = l[j], l[i]
}
func (l childList) Search(pattern string) *Route {
	index := sort.Search(l.Len(), func(i int) bool {
		return l[i].pattern >= pattern
	})
	if index < l.Len() && l[index].pattern == pattern {
		return l[index]
	}
	return nil
}
type verbFlag uint8
const (
	flagGet = verbFlag(1) << iota
	flagHead
	flagPost
	flagPut
	flagPatch
	flagDelete
	flagConnect
	flagOptions
	flagAny = ^verbFlag(0)
)
func (f verbFlag) Matches(v verbFlag) bool {
	if v == 0 {
		return false
	}
	return f&v == v
}
func getVerbFlagForMethod(method string) verbFlag {
	switch method {
	case http.MethodGet:
		return flagGet
	case http.MethodHead:
		return flagHead
	case http.MethodPost:
		return flagPost
	case http.MethodPut:
		return flagPut
	case http.MethodPatch:
		return flagPatch
	case http.MethodDelete:
		return flagDelete
	case http.MethodConnect:
		return flagConnect
	case http.MethodOptions:
		return flagOptions
	default:
		panic("powermux: getVerbFlag: not a valid http method: " + method)
	}
}
type middlewareForVerb struct {
	mid  Middleware
	verb verbFlag
}
var pathPartsPool = &sync.Pool{
	New: func() interface{} {
		return make([]string, 0, 5)
	},
}
type Route struct {
	pattern string
	fullPath string
	isParam bool
	paramName string
	isWildcard bool
	middleware []*middlewareForVerb
	children childList
	paramChild *Route
	wildcardChild *Route
	handlers map[string]http.Handler
}
func newRoute() *Route {
	return &Route{
		handlers:   make(map[string]http.Handler),
		middleware: make([]*middlewareForVerb, 0),
		children:   make([]*Route, 0),
	}
}
func (r *Route) execute(ex *routeExecution, method, pattern string) {
	pathParts := pathPartsPool.Get().([]string)[0:0]
	pathParts = append(pathParts, "")
	start := 1
	for i := 1; i < len(pattern); i++ {
		if pattern[i] == '/' {
			pathParts = append(pathParts, pattern[start:i])
			i++
			start = i
		}
	}
	if pattern != "/" {
		pathParts = append(pathParts, pattern[start:])
	}
	r.getExecution(method, pathParts, ex)
	pathPartsPool.Put(pathParts)
}
func (r *Route) getExecution(method string, pathParts []string, ex *routeExecution) {
	curRoute := r
	verb := getVerbFlagForMethod(method)
	for {
		for i := range curRoute.middleware {
			if curRoute.middleware[i].verb.Matches(verb) {
				ex.middleware = append(ex.middleware, curRoute.middleware[i].mid)
			}
		}
		if h, ok := curRoute.handlers[notFound]; ok {
			ex.notFound = h
		}
		if method == http.MethodOptions {
			if h, ok := curRoute.handlers[http.MethodOptions]; ok {
				ex.handler = h
			}
		}
		if curRoute.isParam {
			value, _ := url.PathUnescape(pathParts[0])
			ex.params[curRoute.paramName] = value
		}
		if len(pathParts) == 1 || curRoute.isWildcard {
			curRoute.getHandler(method, ex)
			if curRoute.fullPath == "" {
				ex.pattern = "/"
			} else {
				ex.pattern = curRoute.fullPath
			}
			return
		}
		if child := curRoute.children.Search(pathParts[1]); child != nil {
			pathParts = pathParts[1:]
			curRoute = child
			continue
		}
		if curRoute.paramChild != nil {
			pathParts = pathParts[1:]
			curRoute = curRoute.paramChild
			continue
		}
		if curRoute.wildcardChild != nil {
			pathParts = pathParts[1:]
			curRoute = curRoute.wildcardChild
			continue
		}
		return
	}
}
func (r *Route) getHandler(method string, ex *routeExecution) {
	if h, ok := r.handlers[method]; ok {
		ex.handler = h
		return
	}
	if method == http.MethodHead {
		if h, ok := r.handlers[http.MethodGet]; ok {
			ex.handler = h
			return
		}
	}
	if h, ok := r.handlers[methodAny]; ok {
		ex.handler = h
		return
	}
	if ex.handler == nil {
		ex.handler = r.methodNotAllowed()
	}
	return
}