func (be BindError) Error() string {
	if be.field != "" && be.typ != nil {
		return fmt.Sprintf(
			"binding error on field '%s' of type '%s': %s",
			be.field,
			be.typ.Name(),
			be.message,
		)
	}
	return fmt.Sprintf("binding error: %s", be.message)
}
Error implements the builtin error interface for BindError.
package tonic
import (
	"encoding"
	"errors"
	"fmt"
	"io"
	"net/http"
	"reflect"
	"strconv"
	"strings"
	"sync"
	"time"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	validator "github.com/go-playground/validator/v10"
)
const DefaultMaxBodyBytes = 256 * 1024
const (
	QueryTag      = "query"
	PathTag       = "path"
	HeaderTag     = "header"
	EnumTag       = "enum"
	RequiredTag   = "required"
	DefaultTag    = "default"
	ValidationTag = "validate"
	ExplodeTag    = "explode"
)
const (
	defaultMediaType    = "application/json"
	tonicRoutesInfos    = "_tonic_route_infos"
	tonicWantRouteInfos = "_tonic_want_route_infos"
)
var (
	errorHook  ErrorHook  = DefaultErrorHook
	bindHook   BindHook   = DefaultBindingHook
	renderHook RenderHook = DefaultRenderHook
	execHook   ExecHook   = DefaultExecHook
	mediaType = defaultMediaType
	routes   = make(map[string]*Route)
	routesMu = sync.Mutex{}
	funcs    = make(map[string]struct{})
	funcsMu  = sync.Mutex{}
)
type BindHook func(*gin.Context, interface{}) error
type RenderHook func(*gin.Context, int, interface{})
type ErrorHook func(*gin.Context, error) (int, interface{})
type ExecHook func(*gin.Context, gin.HandlerFunc, string)
func DefaultErrorHook(c *gin.Context, e error) (int, interface{}) {
	return http.StatusBadRequest, gin.H{
		"error": e.Error(),
	}
}
var DefaultBindingHook BindHook = DefaultBindingHookMaxBodyBytes(DefaultMaxBodyBytes)
func DefaultBindingHookMaxBodyBytes(maxBodyBytes int64) BindHook {
	return func(c *gin.Context, i interface{}) error {
		c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, maxBodyBytes)
		if c.Request.ContentLength == 0 || c.Request.Method == http.MethodGet {
			return nil
		}
		if err := c.ShouldBindWith(i, binding.JSON); err != nil && err != io.EOF {
			return fmt.Errorf("error parsing request body: %s", err.Error())
		}
		return nil
	}
}
func DefaultRenderHook(c *gin.Context, statusCode int, payload interface{}) {
	var status int
	if c.Writer.Written() {
		status = c.Writer.Status()
	} else {
		status = statusCode
	}
	if payload != nil {
		if gin.IsDebugging() {
			c.IndentedJSON(status, payload)
		} else {
			c.JSON(status, payload)
		}
	} else {
		c.String(status, "")
	}
}
func DefaultExecHook(c *gin.Context, h gin.HandlerFunc, fname string) {
	h(c)
}
func GetRoutes() map[string]*Route {
	return routes
}
func MediaType() string {
	return defaultMediaType
}
func GetErrorHook() ErrorHook {
	return errorHook
}
func SetErrorHook(eh ErrorHook) {
	if eh != nil {
		errorHook = eh
	}
}
func GetBindHook() BindHook {
	return bindHook
}
func SetBindHook(bh BindHook) {
	if bh != nil {
		bindHook = bh
	}
}
func GetRenderHook() RenderHook {
	return renderHook
}
func SetRenderHook(rh RenderHook, mt string) {
	if rh != nil {
		renderHook = rh
	}
	if mt != "" {
		mediaType = mt
	}
}
func SetExecHook(eh ExecHook) {
	if eh != nil {
		execHook = eh
	}
}
func GetExecHook() ExecHook {
	return execHook
}
func Description(s string) func(*Route) {
	return func(r *Route) {
		r.description = s
	}
}
func Summary(s string) func(*Route) {
	return func(r *Route) {
		r.summary = s
	}
}
func Deprecated(b bool) func(*Route) {
	return func(r *Route) {
		r.deprecated = b
	}
}
func Tags(tags []string) func(*Route) {
	return func(r *Route) {
		r.tags = tags
	}
}
type BindError struct {
	validationErr error
	message       string
	typ           reflect.Type
	field         string
}