func (mx *Mux) Group(fn func(r Router)) {
	im := mx.With().(*Mux)
	fn(im)
}
Group creates a new inline-Mux with a fresh middleware stack. It's useful
for a group of handlers along the same routing path that use an additional
set of middlewares. See _examples/.
package phi
import (
	"fmt"
	"strings"
	"sync"
	"github.com/valyala/fasthttp"
)
var _ Router = &Mux{}
type Mux struct {
	tree *node
	middlewares Middlewares
	inline bool
	parent *Mux
	handler Handler
	pool sync.Pool
	notFoundHandler HandlerFunc
	methodNotAllowedHandler HandlerFunc
}
func NewMux() *Mux {
	mux := &Mux{tree: &node{}}
	mux.pool.New = func() interface{} {
		return NewRouteContext()
	}
	return mux
}
func (mx *Mux) ServeFastHTTP(ctx *fasthttp.RequestCtx) {
	if mx.handler == nil {
		panic("phi: attempting to route to a mux with no handlers.")
	}
	rctx, _ := ctx.UserValue(RouteCtxKey).(*Context)
	if rctx != nil {
		mx.handler.ServeFastHTTP(ctx)
		return
	}
	rctx = mx.pool.Get().(*Context)
	rctx.Reset()
	rctx.Routes = mx
	ctx.SetUserValue(RouteCtxKey, rctx)
	mx.handler.ServeFastHTTP(ctx)
	mx.pool.Put(rctx)
}
func (mx *Mux) Use(middlewares ...Middleware) {
	if mx.handler != nil {
		panic("phi: all middlewares must be defined before routes on a mux")
	}
	mx.middlewares = append(mx.middlewares, middlewares...)
}
func (mx *Mux) Handle(pattern string, handler HandlerFunc) {
	mx.handle(mALL, pattern, handler)
}
func (mx *Mux) Method(method, pattern string, handler HandlerFunc) {
	m, ok := methodMap[strings.ToUpper(method)]
	if !ok {
		panic(fmt.Sprintf("phi: '%s' http method is not supported.", method))
	}
	mx.handle(m, pattern, handler)
}
func (mx *Mux) Connect(pattern string, handlerFn HandlerFunc) {
	mx.handle(mCONNECT, pattern, handlerFn)
}
func (mx *Mux) Delete(pattern string, handlerFn HandlerFunc) {
	mx.handle(mDELETE, pattern, handlerFn)
}
func (mx *Mux) Get(pattern string, handlerFn HandlerFunc) {
	mx.handle(mGET, pattern, handlerFn)
}
func (mx *Mux) Head(pattern string, handlerFn HandlerFunc) {
	mx.handle(mHEAD, pattern, handlerFn)
}
func (mx *Mux) Options(pattern string, handlerFn HandlerFunc) {
	mx.handle(mOPTIONS, pattern, handlerFn)
}
func (mx *Mux) Patch(pattern string, handlerFn HandlerFunc) {
	mx.handle(mPATCH, pattern, handlerFn)
}
func (mx *Mux) Post(pattern string, handlerFn HandlerFunc) {
	mx.handle(mPOST, pattern, handlerFn)
}
func (mx *Mux) Put(pattern string, handlerFn HandlerFunc) {
	mx.handle(mPUT, pattern, handlerFn)
}
func (mx *Mux) Trace(pattern string, handlerFn HandlerFunc) {
	mx.handle(mTRACE, pattern, handlerFn)
}
func (mx *Mux) NotFound(handlerFn HandlerFunc) {
	m := mx
	hFn := handlerFn
	if mx.inline && mx.parent != nil {
		m = mx.parent
		hFn = Chain(mx.middlewares...).HandlerFunc(hFn).ServeFastHTTP
	}
	m.notFoundHandler = hFn
	m.updateSubRoutes(func(subMux *Mux) {
		if subMux.notFoundHandler == nil {
			subMux.NotFound(hFn)
		}
	})
}
func (mx *Mux) MethodNotAllowed(handlerFn HandlerFunc) {
	m := mx
	hFn := handlerFn
	if mx.inline && mx.parent != nil {
		m = mx.parent
		hFn = Chain(mx.middlewares...).HandlerFunc(hFn).ServeFastHTTP
	}
	m.methodNotAllowedHandler = hFn
	m.updateSubRoutes(func(subMux *Mux) {
		if subMux.methodNotAllowedHandler == nil {
			subMux.MethodNotAllowed(hFn)
		}
	})
}
func (mx *Mux) With(middlewares ...Middleware) Router {
	if !mx.inline && mx.handler == nil {
		mx.buildRouteHandler()
	}
	var mws Middlewares
	if mx.inline {
		mws = make(Middlewares, len(mx.middlewares))
		copy(mws, mx.middlewares)
	}
	mws = append(mws, middlewares...)
	im := &Mux{inline: true, parent: mx, tree: mx.tree, middlewares: mws}
	return im
}