func (v *Validate) RegisterValidation(tag string, fn Func) error {
	return v.RegisterValidationCtx(tag, wrapFunc(fn))
}
RegisterValidation adds a validation with the given tag

NOTES:
- if the key already exists, the previous validation function will be replaced.
- this method is not thread-safe it is intended that these all be registered prior to any validation
package validator
import (
	"context"
	"errors"
	"fmt"
	"reflect"
	"strings"
	"sync"
	"time"
	ut "github.com/go-playground/universal-translator"
)
const (
	defaultTagName     = "validate"
	utf8HexComma       = "0x2C"
	utf8Pipe           = "0x7C"
	tagSeparator       = ","
	orSeparator        = "|"
	tagKeySeparator    = "="
	structOnlyTag      = "structonly"
	noStructLevelTag   = "nostructlevel"
	omitempty          = "omitempty"
	isdefault          = "isdefault"
	skipValidationTag  = "-"
	diveTag            = "dive"
	keysTag            = "keys"
	endKeysTag         = "endkeys"
	requiredTag        = "required"
	namespaceSeparator = "."
	leftBracket        = "["
	rightBracket       = "]"
	restrictedTagChars = ".[],|=+()`~!@#$%^&*\\\"/?<>{}"
	restrictedAliasErr = "Alias '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation"
	restrictedTagErr   = "Tag '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation"
)
var (
	timeType      = reflect.TypeOf(time.Time{})
	defaultCField = &cField{namesEqual: true}
)
type FilterFunc func(ns []byte) bool
type CustomTypeFunc func(field reflect.Value) interface{}
type TagNameFunc func(field reflect.StructField) string
type Validate struct {
	tagName          string
	pool             *sync.Pool
	hasCustomFuncs   bool
	hasTagNameFunc   bool
	tagNameFunc      TagNameFunc
	structLevelFuncs map[reflect.Type]StructLevelFuncCtx
	customFuncs      map[reflect.Type]CustomTypeFunc
	aliases          map[string]string
	validations      map[string]FuncCtx
	transTagFunc     map[ut.Translator]map[string]TranslationFunc  
	tagCache         *tagCache
	structCache      *structCache
}
func New() *Validate {
	tc := new(tagCache)
	tc.m.Store(make(map[string]*cTag))
	sc := new(structCache)
	sc.m.Store(make(map[reflect.Type]*cStruct))
	v := &Validate{
		tagName:     defaultTagName,
		aliases:     make(map[string]string, len(bakedInAliases)),
		validations: make(map[string]FuncCtx, len(bakedInValidators)),
		tagCache:    tc,
		structCache: sc,
	}
	for k, val := range bakedInAliases {
		v.RegisterAlias(k, val)
	}
	for k, val := range bakedInValidators {
		_ = v.registerValidation(k, wrapFunc(val), true)
	}
	v.pool = &sync.Pool{
		New: func() interface{} {
			return &validate{
				v:        v,
				ns:       make([]byte, 0, 64),
				actualNs: make([]byte, 0, 64),
				misc:     make([]byte, 32),
			}
		},
	}
	return v
}
func (v *Validate) SetTagName(name string) {
	v.tagName = name
}
func (v *Validate) RegisterTagNameFunc(fn TagNameFunc) {
	v.tagNameFunc = fn
	v.hasTagNameFunc = true
}