func checkMatchStyleAll(s *Segment) (bind string, capture int, ok bool) {
	if len(s.Elements) == 0 ||
		s.Elements[0].BindParameters == nil ||
		len(s.Elements[0].BindParameters.Parameters) == 0 ||
		s.Elements[0].BindParameters.Parameters[0].Value.Literal == nil ||
		*s.Elements[0].BindParameters.Parameters[0].Value.Literal != "**" {
		return "", 0, false
	}
	bind = s.Elements[0].BindParameters.Parameters[0].Ident
	if len(s.Elements[0].BindParameters.Parameters) > 1 &&
		s.Elements[0].BindParameters.Parameters[1].Ident == "capture" &&
		s.Elements[0].BindParameters.Parameters[1].Value.Literal != nil {
		capture, _ = strconv.Atoi(*s.Elements[0].BindParameters.Parameters[1].Value.Literal)
	}
	return bind, capture, true
}
checkMatchStyleAll returns true if the Segment is match all style, along with
its bind parameter name and capture limit. The capture is 0 when undefined.
package route
import (
	"bytes"
	"regexp"
	"strconv"
	"strings"
	"github.com/pkg/errors"
)
type MatchStyle int8
const (
	matchStyleNone        MatchStyle = iota
	matchStyleStatic                  
	matchStyleRegex                   
	matchStylePlaceholder             
	matchStyleAll                     
)
type Leaf interface {
	URLPath(vals map[string]string, withOptional bool) string
	Route() string
	Handler() Handler
	Static() bool
	getParent() Tree
	getSegment() *Segment
	getMatchStyle() MatchStyle
	match(segment string, params Params) bool
}
type baseLeaf struct {
	parent  Tree      
	route   *Route    
	segment *Segment  
	handler Handler   
}
func (l *baseLeaf) getParent() Tree {
	return l.parent
}
func (l *baseLeaf) getSegment() *Segment {
	return l.segment
}
func (l *baseLeaf) URLPath(vals map[string]string, withOptional bool) string {
	var buf bytes.Buffer
	for _, s := range l.route.Segments {
		if s.Optional && !withOptional {
			break
		}
		buf.WriteString("/")
		for _, e := range s.Elements {
			if e.Ident != nil {
				buf.WriteString(*e.Ident)
				continue
			} else if e.BindIdent != nil {
				buf.WriteString("{")
				buf.WriteString(*e.BindIdent)
				buf.WriteString("}")
				continue
			} else if e.BindParameters == nil || len(e.BindParameters.Parameters) == 0 {
				buf.WriteString("???")
				continue
			}
			buf.WriteString("{")
			buf.WriteString(e.BindParameters.Parameters[0].Ident)
			buf.WriteString("}")
		}
	}
	pairs := make([]string, 0, len(vals)*2)
	for k, v := range vals {
		pairs = append(pairs, "{"+k+"}", v)
	}
	return strings.NewReplacer(pairs...).Replace(buf.String())
}
func (l *baseLeaf) Route() string {
	return l.route.String()
}
func (l *baseLeaf) Handler() Handler {
	return l.handler
}
func (l *baseLeaf) Static() bool {
	return false
}
type staticLeaf struct {
	baseLeaf
}
func (l *staticLeaf) getMatchStyle() MatchStyle {
	return matchStyleStatic
}
func (l *staticLeaf) match(segment string, _ Params) bool {
	return l.segment.String()[1:] == segment  
}
func (l *staticLeaf) Static() bool {
	ancestor := l.parent
	for ancestor != nil {
		if ancestor.getMatchStyle() > matchStyleStatic {
			return false
		}
		ancestor = ancestor.getParent()
	}
	return true
}
type regexLeaf struct {
	baseLeaf
	regexp *regexp.Regexp  
	binds  []string        
}
func (l *regexLeaf) getMatchStyle() MatchStyle {
	return matchStyleRegex
}
func (l *regexLeaf) match(segment string, params Params) bool {
	submatches := l.regexp.FindStringSubmatch(segment)
	if len(submatches) < len(l.binds)+1 {
		return false
	}
	for i, bind := range l.binds {
		params[bind] = submatches[i+1]
	}
	return true
}
type placeholderLeaf struct {
	baseLeaf
	bind string  
}
func (l *placeholderLeaf) getMatchStyle() MatchStyle {
	return matchStylePlaceholder
}
func (l *placeholderLeaf) match(segment string, params Params) bool {
	params[l.bind] = segment
	return true
}
type matchAllLeaf struct {
	baseLeaf
	bind    string  
	capture int     
}
func (l *matchAllLeaf) getMatchStyle() MatchStyle {
	return matchStyleAll
}
func (l *matchAllLeaf) match(segment string, params Params) bool {
	params[l.bind] = segment
	return true
}
func (l *matchAllLeaf) matchAll(path string, segment string, next int, params Params) bool {
	if l.capture > 0 && l.capture < strings.Count(path[next-1:], "/")+1 {
		return false
	}
	params[l.bind] = segment + "/" + path[next:]
	return true
}
func isMatchStyleStatic(s *Segment) bool {
	return len(s.Elements) == 1 && s.Elements[0].Ident != nil
}
func checkMatchStylePlaceholder(s *Segment) (bind string, ok bool) {
	if len(s.Elements) == 1 &&
		s.Elements[0].BindIdent != nil {
		return *s.Elements[0].BindIdent, true
	}
	return "", false
}