test support go1.18 (#2990)

This commit is contained in:
thinkerou 2022-03-21 09:43:17 +08:00 committed by GitHub
parent 9701b651b7
commit 2bde107686
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 214 additions and 174 deletions

10
any.go Normal file
View File

@ -0,0 +1,10 @@
// Copyright 2022 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
//go:build !go1.18
// +build !go1.18
package gin
type any = interface{}

10
binding/any.go Normal file
View File

@ -0,0 +1,10 @@
// Copyright 2022 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
//go:build !go1.18
// +build !go1.18
package binding
type any = interface{}

View File

@ -29,21 +29,21 @@ const (
// the form POST.
type Binding interface {
Name() string
Bind(*http.Request, interface{}) error
Bind(*http.Request, any) error
}
// BindingBody adds BindBody method to Binding. BindBody is similar with Bind,
// but it reads the body from supplied bytes instead of req.Body.
type BindingBody interface {
Binding
BindBody([]byte, interface{}) error
BindBody([]byte, any) error
}
// BindingUri adds BindUri method to Binding. BindUri is similar with Bind,
// but it reads the Params.
type BindingUri interface {
Name() string
BindUri(map[string][]string, interface{}) error
BindUri(map[string][]string, any) error
}
// StructValidator is the minimal interface which needs to be implemented in
@ -57,11 +57,11 @@ type StructValidator interface {
// If the received type is a struct or pointer to a struct, the validation should be performed.
// If the struct is not valid or the validation itself fails, a descriptive error should be returned.
// Otherwise nil must be returned.
ValidateStruct(interface{}) error
ValidateStruct(any) error
// Engine returns the underlying validator engine which powers the
// StructValidator implementation.
Engine() interface{}
Engine() any
}
// Validator is the default validator which implements the StructValidator
@ -110,7 +110,7 @@ func Default(method, contentType string) Binding {
}
}
func validate(obj interface{}) error {
func validate(obj any) error {
if Validator == nil {
return nil
}

View File

@ -27,21 +27,21 @@ const (
// the form POST.
type Binding interface {
Name() string
Bind(*http.Request, interface{}) error
Bind(*http.Request, any) error
}
// BindingBody adds BindBody method to Binding. BindBody is similar with Bind,
// but it reads the body from supplied bytes instead of req.Body.
type BindingBody interface {
Binding
BindBody([]byte, interface{}) error
BindBody([]byte, any) error
}
// BindingUri adds BindUri method to Binding. BindUri is similar with Bind,
// but it reads the Params.
type BindingUri interface {
Name() string
BindUri(map[string][]string, interface{}) error
BindUri(map[string][]string, any) error
}
// StructValidator is the minimal interface which needs to be implemented in
@ -54,11 +54,11 @@ type StructValidator interface {
// If the received type is a struct or pointer to a struct, the validation should be performed.
// If the struct is not valid or the validation itself fails, a descriptive error should be returned.
// Otherwise nil must be returned.
ValidateStruct(interface{}) error
ValidateStruct(any) error
// Engine returns the underlying validator engine which powers the
// StructValidator implementation.
Engine() interface{}
Engine() any
}
// Validator is the default validator which implements the StructValidator
@ -104,7 +104,7 @@ func Default(method, contentType string) Binding {
}
}
func validate(obj interface{}) error {
func validate(obj any) error {
if Validator == nil {
return nil
}

View File

@ -61,11 +61,11 @@ type FooDefaultBarStruct struct {
}
type FooStructUseNumber struct {
Foo interface{} `json:"foo" binding:"required"`
Foo any `json:"foo" binding:"required"`
}
type FooStructDisallowUnknownFields struct {
Foo interface{} `json:"foo" binding:"required"`
Foo any `json:"foo" binding:"required"`
}
type FooBarStructForTimeType struct {
@ -93,7 +93,7 @@ type FooStructForTimeTypeFailLocation struct {
}
type FooStructForMapType struct {
MapFoo map[string]interface{} `form:"map_foo"`
MapFoo map[string]any `form:"map_foo"`
}
type FooStructForIgnoreFormTag struct {
@ -106,7 +106,7 @@ type InvalidNameType struct {
type InvalidNameMapType struct {
TestName struct {
MapFoo map[string]interface{} `form:"map_foo"`
MapFoo map[string]any `form:"map_foo"`
}
}
@ -128,7 +128,7 @@ type FooStructForStructPointerType struct {
type FooStructForSliceMapType struct {
// Unknown type: not support map
SliceMapFoo []map[string]interface{} `form:"slice_map_foo"`
SliceMapFoo []map[string]any `form:"slice_map_foo"`
}
type FooStructForBoolType struct {
@ -141,7 +141,7 @@ type FooStructForStringPtrType struct {
}
type FooStructForMapPtrType struct {
PtrBar *map[string]interface{} `form:"ptr_bar"`
PtrBar *map[string]any `form:"ptr_bar"`
}
func TestBindingDefault(t *testing.T) {
@ -768,7 +768,7 @@ func TestHeaderBinding(t *testing.T) {
req.Header.Add("fail", `{fail:fail}`)
type failStruct struct {
Fail map[string]interface{} `header:"fail"`
Fail map[string]any `header:"fail"`
}
err := h.Bind(req, &failStruct{})
@ -789,11 +789,11 @@ func TestUriBinding(t *testing.T) {
assert.Equal(t, "thinkerou", tag.Name)
type NotSupportStruct struct {
Name map[string]interface{} `uri:"name"`
Name map[string]any `uri:"name"`
}
var not NotSupportStruct
assert.Error(t, b.BindUri(m, &not))
assert.Equal(t, map[string]interface{}(nil), not.Name)
assert.Equal(t, map[string]any(nil), not.Name)
}
func TestUriInnerBinding(t *testing.T) {

View File

@ -46,7 +46,7 @@ func (err SliceValidationError) Error() string {
var _ StructValidator = &defaultValidator{}
// ValidateStruct receives any kind of type, but only performed struct or pointer to struct type.
func (v *defaultValidator) ValidateStruct(obj interface{}) error {
func (v *defaultValidator) ValidateStruct(obj any) error {
if obj == nil {
return nil
}
@ -75,7 +75,7 @@ func (v *defaultValidator) ValidateStruct(obj interface{}) error {
}
// validateStruct receives struct type
func (v *defaultValidator) validateStruct(obj interface{}) error {
func (v *defaultValidator) validateStruct(obj any) error {
v.lazyinit()
return v.validate.Struct(obj)
}
@ -84,7 +84,7 @@ func (v *defaultValidator) validateStruct(obj interface{}) error {
// Validator instance. This is useful if you want to register custom validations
// or struct level validations. See validator GoDoc for more info -
// https://pkg.go.dev/github.com/go-playground/validator/v10
func (v *defaultValidator) Engine() interface{} {
func (v *defaultValidator) Engine() any {
v.lazyinit()
return v.validate
}

View File

@ -54,7 +54,7 @@ func TestDefaultValidator(t *testing.T) {
tests := []struct {
name string
v *defaultValidator
obj interface{}
obj any
wantErr bool
}{
{"validate nil obj", &defaultValidator{}, nil, false},

View File

@ -19,7 +19,7 @@ func (formBinding) Name() string {
return "form"
}
func (formBinding) Bind(req *http.Request, obj interface{}) error {
func (formBinding) Bind(req *http.Request, obj any) error {
if err := req.ParseForm(); err != nil {
return err
}
@ -36,7 +36,7 @@ func (formPostBinding) Name() string {
return "form-urlencoded"
}
func (formPostBinding) Bind(req *http.Request, obj interface{}) error {
func (formPostBinding) Bind(req *http.Request, obj any) error {
if err := req.ParseForm(); err != nil {
return err
}
@ -50,7 +50,7 @@ func (formMultipartBinding) Name() string {
return "multipart/form-data"
}
func (formMultipartBinding) Bind(req *http.Request, obj interface{}) error {
func (formMultipartBinding) Bind(req *http.Request, obj any) error {
if err := req.ParseMultipartForm(defaultMemory); err != nil {
return err
}

View File

@ -26,24 +26,24 @@ var (
ErrConvertToMapString = errors.New("can not convert to map of strings")
)
func mapURI(ptr interface{}, m map[string][]string) error {
func mapURI(ptr any, m map[string][]string) error {
return mapFormByTag(ptr, m, "uri")
}
func mapForm(ptr interface{}, form map[string][]string) error {
func mapForm(ptr any, form map[string][]string) error {
return mapFormByTag(ptr, form, "form")
}
func MapFormWithTag(ptr interface{}, form map[string][]string, tag string) error {
func MapFormWithTag(ptr any, form map[string][]string, tag string) error {
return mapFormByTag(ptr, form, tag)
}
var emptyField = reflect.StructField{}
func mapFormByTag(ptr interface{}, form map[string][]string, tag string) error {
func mapFormByTag(ptr any, form map[string][]string, tag string) error {
// Check if ptr is a map
ptrVal := reflect.ValueOf(ptr)
var pointed interface{}
var pointed any
if ptrVal.Kind() == reflect.Ptr {
ptrVal = ptrVal.Elem()
pointed = ptrVal.Interface()
@ -73,7 +73,7 @@ func (form formSource) TrySet(value reflect.Value, field reflect.StructField, ta
return setByForm(value, field, form, tagValue, opt)
}
func mappingByPtr(ptr interface{}, setter setter, tag string) error {
func mappingByPtr(ptr any, setter setter, tag string) error {
_, err := mapping(reflect.ValueOf(ptr), emptyField, setter, tag)
return err
}
@ -376,7 +376,7 @@ func head(str, sep string) (head string, tail string) {
return str[:idx], str[idx+len(sep):]
}
func setFormMap(ptr interface{}, form map[string][]string) error {
func setFormMap(ptr any, form map[string][]string) error {
el := reflect.TypeOf(ptr).Elem()
if el.Kind() == reflect.Slice {

View File

@ -18,9 +18,9 @@ func TestMappingBaseTypes(t *testing.T) {
}
for _, tt := range []struct {
name string
value interface{}
value any
form string
expect interface{}
expect any
}{
{"base type", struct{ F int }{}, "9", int(9)},
{"base type", struct{ F int8 }{}, "9", int8(9)},

View File

@ -12,7 +12,7 @@ func (headerBinding) Name() string {
return "header"
}
func (headerBinding) Bind(req *http.Request, obj interface{}) error {
func (headerBinding) Bind(req *http.Request, obj any) error {
if err := mapHeader(obj, req.Header); err != nil {
return err
@ -21,7 +21,7 @@ func (headerBinding) Bind(req *http.Request, obj interface{}) error {
return validate(obj)
}
func mapHeader(ptr interface{}, h map[string][]string) error {
func mapHeader(ptr any, h map[string][]string) error {
return mappingByPtr(ptr, headerSource(h), "header")
}

View File

@ -30,18 +30,18 @@ func (jsonBinding) Name() string {
return "json"
}
func (jsonBinding) Bind(req *http.Request, obj interface{}) error {
func (jsonBinding) Bind(req *http.Request, obj any) error {
if req == nil || req.Body == nil {
return errors.New("invalid request")
}
return decodeJSON(req.Body, obj)
}
func (jsonBinding) BindBody(body []byte, obj interface{}) error {
func (jsonBinding) BindBody(body []byte, obj any) error {
return decodeJSON(bytes.NewReader(body), obj)
}
func decodeJSON(r io.Reader, obj interface{}) error {
func decodeJSON(r io.Reader, obj any) error {
decoder := json.NewDecoder(r)
if EnableDecoderUseNumber {
decoder.UseNumber()

View File

@ -21,15 +21,15 @@ func (msgpackBinding) Name() string {
return "msgpack"
}
func (msgpackBinding) Bind(req *http.Request, obj interface{}) error {
func (msgpackBinding) Bind(req *http.Request, obj any) error {
return decodeMsgPack(req.Body, obj)
}
func (msgpackBinding) BindBody(body []byte, obj interface{}) error {
func (msgpackBinding) BindBody(body []byte, obj any) error {
return decodeMsgPack(bytes.NewReader(body), obj)
}
func decodeMsgPack(r io.Reader, obj interface{}) error {
func decodeMsgPack(r io.Reader, obj any) error {
cdc := new(codec.MsgpackHandle)
if err := codec.NewDecoder(r, cdc).Decode(&obj); err != nil {
return err

View File

@ -26,7 +26,7 @@ func TestMsgpackBindingBindBody(t *testing.T) {
assert.Equal(t, "FOO", s.Foo)
}
func msgpackBody(t *testing.T, obj interface{}) []byte {
func msgpackBody(t *testing.T, obj any) []byte {
var bs bytes.Buffer
h := &codec.MsgpackHandle{}
err := codec.NewEncoder(&bs, h).Encode(obj)

View File

@ -76,7 +76,7 @@ func TestFormMultipartBindingBindError(t *testing.T) {
for _, tt := range []struct {
name string
s interface{}
s any
}{
{"wrong type", &struct {
Files int `form:"file"`

View File

@ -18,7 +18,7 @@ func (protobufBinding) Name() string {
return "protobuf"
}
func (b protobufBinding) Bind(req *http.Request, obj interface{}) error {
func (b protobufBinding) Bind(req *http.Request, obj any) error {
buf, err := ioutil.ReadAll(req.Body)
if err != nil {
return err
@ -26,7 +26,7 @@ func (b protobufBinding) Bind(req *http.Request, obj interface{}) error {
return b.BindBody(buf, obj)
}
func (protobufBinding) BindBody(body []byte, obj interface{}) error {
func (protobufBinding) BindBody(body []byte, obj any) error {
msg, ok := obj.(proto.Message)
if !ok {
return errors.New("obj is not ProtoMessage")

View File

@ -12,7 +12,7 @@ func (queryBinding) Name() string {
return "query"
}
func (queryBinding) Bind(req *http.Request, obj interface{}) error {
func (queryBinding) Bind(req *http.Request, obj any) error {
values := req.URL.Query()
if err := mapForm(obj, values); err != nil {
return err

View File

@ -10,7 +10,7 @@ func (uriBinding) Name() string {
return "uri"
}
func (uriBinding) BindUri(m map[string][]string, obj interface{}) error {
func (uriBinding) BindUri(m map[string][]string, obj any) error {
if err := mapURI(obj, m); err != nil {
return err
}

View File

@ -59,7 +59,7 @@ type structNoValidationValues struct {
StructSlice []substructNoValidation
InterfaceSlice []testInterface
UniversalInterface interface{}
UniversalInterface any
CustomInterface testInterface
FloatMap map[string]float32
@ -169,7 +169,7 @@ func TestValidateNoValidationPointers(t *testing.T) {
//assert.Equal(t, origin, test)
}
type Object map[string]interface{}
type Object map[string]any
func TestValidatePrimitives(t *testing.T) {
obj := Object{"foo": "bar", "bar": 1}

View File

@ -17,14 +17,14 @@ func (xmlBinding) Name() string {
return "xml"
}
func (xmlBinding) Bind(req *http.Request, obj interface{}) error {
func (xmlBinding) Bind(req *http.Request, obj any) error {
return decodeXML(req.Body, obj)
}
func (xmlBinding) BindBody(body []byte, obj interface{}) error {
func (xmlBinding) BindBody(body []byte, obj any) error {
return decodeXML(bytes.NewReader(body), obj)
}
func decodeXML(r io.Reader, obj interface{}) error {
func decodeXML(r io.Reader, obj any) error {
decoder := xml.NewDecoder(r)
if err := decoder.Decode(obj); err != nil {
return err

View File

@ -18,15 +18,15 @@ func (yamlBinding) Name() string {
return "yaml"
}
func (yamlBinding) Bind(req *http.Request, obj interface{}) error {
func (yamlBinding) Bind(req *http.Request, obj any) error {
return decodeYAML(req.Body, obj)
}
func (yamlBinding) BindBody(body []byte, obj interface{}) error {
func (yamlBinding) BindBody(body []byte, obj any) error {
return decodeYAML(bytes.NewReader(body), obj)
}
func decodeYAML(r io.Reader, obj interface{}) error {
func decodeYAML(r io.Reader, obj any) error {
decoder := yaml.NewDecoder(r)
if err := decoder.Decode(obj); err != nil {
return err

View File

@ -62,7 +62,7 @@ type Context struct {
mu sync.RWMutex
// Keys is a key/value pair exclusively for the context of each request.
Keys map[string]interface{}
Keys map[string]any
// Errors is a list of errors attached to all the handlers/middlewares who used this context.
Errors errorMsgs
@ -115,7 +115,7 @@ func (c *Context) Copy() *Context {
cp.Writer = &cp.writermem
cp.index = abortIndex
cp.handlers = nil
cp.Keys = map[string]interface{}{}
cp.Keys = map[string]any{}
for k, v := range c.Keys {
cp.Keys[k] = v
}
@ -194,7 +194,7 @@ func (c *Context) AbortWithStatus(code int) {
// AbortWithStatusJSON calls `Abort()` and then `JSON` internally.
// This method stops the chain, writes the status code and return a JSON body.
// It also sets the Content-Type as "application/json".
func (c *Context) AbortWithStatusJSON(code int, jsonObj interface{}) {
func (c *Context) AbortWithStatusJSON(code int, jsonObj any) {
c.Abort()
c.JSON(code, jsonObj)
}
@ -240,10 +240,10 @@ func (c *Context) Error(err error) *Error {
// Set is used to store a new key/value pair exclusively for this context.
// It also lazy initializes c.Keys if it was not used previously.
func (c *Context) Set(key string, value interface{}) {
func (c *Context) Set(key string, value any) {
c.mu.Lock()
if c.Keys == nil {
c.Keys = make(map[string]interface{})
c.Keys = make(map[string]any)
}
c.Keys[key] = value
@ -252,7 +252,7 @@ func (c *Context) Set(key string, value interface{}) {
// Get returns the value for the given key, ie: (value, true).
// If the value does not exist it returns (nil, false)
func (c *Context) Get(key string) (value interface{}, exists bool) {
func (c *Context) Get(key string) (value any, exists bool) {
c.mu.RLock()
value, exists = c.Keys[key]
c.mu.RUnlock()
@ -260,7 +260,7 @@ func (c *Context) Get(key string) (value interface{}, exists bool) {
}
// MustGet returns the value for the given key if it exists, otherwise it panics.
func (c *Context) MustGet(key string) interface{} {
func (c *Context) MustGet(key string) any {
if value, exists := c.Get(key); exists {
return value
}
@ -348,9 +348,9 @@ func (c *Context) GetStringSlice(key string) (ss []string) {
}
// GetStringMap returns the value associated with the key as a map of interfaces.
func (c *Context) GetStringMap(key string) (sm map[string]interface{}) {
func (c *Context) GetStringMap(key string) (sm map[string]any) {
if val, ok := c.Get(key); ok && val != nil {
sm, _ = val.(map[string]interface{})
sm, _ = val.(map[string]any)
}
return
}
@ -607,39 +607,39 @@ func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error
// It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input.
// It decodes the json payload into the struct specified as a pointer.
// It writes a 400 error and sets Content-Type header "text/plain" in the response if input is not valid.
func (c *Context) Bind(obj interface{}) error {
func (c *Context) Bind(obj any) error {
b := binding.Default(c.Request.Method, c.ContentType())
return c.MustBindWith(obj, b)
}
// BindJSON is a shortcut for c.MustBindWith(obj, binding.JSON).
func (c *Context) BindJSON(obj interface{}) error {
func (c *Context) BindJSON(obj any) error {
return c.MustBindWith(obj, binding.JSON)
}
// BindXML is a shortcut for c.MustBindWith(obj, binding.BindXML).
func (c *Context) BindXML(obj interface{}) error {
func (c *Context) BindXML(obj any) error {
return c.MustBindWith(obj, binding.XML)
}
// BindQuery is a shortcut for c.MustBindWith(obj, binding.Query).
func (c *Context) BindQuery(obj interface{}) error {
func (c *Context) BindQuery(obj any) error {
return c.MustBindWith(obj, binding.Query)
}
// BindYAML is a shortcut for c.MustBindWith(obj, binding.YAML).
func (c *Context) BindYAML(obj interface{}) error {
func (c *Context) BindYAML(obj any) error {
return c.MustBindWith(obj, binding.YAML)
}
// BindHeader is a shortcut for c.MustBindWith(obj, binding.Header).
func (c *Context) BindHeader(obj interface{}) error {
func (c *Context) BindHeader(obj any) error {
return c.MustBindWith(obj, binding.Header)
}
// BindUri binds the passed struct pointer using binding.Uri.
// It will abort the request with HTTP 400 if any error occurs.
func (c *Context) BindUri(obj interface{}) error {
func (c *Context) BindUri(obj any) error {
if err := c.ShouldBindUri(obj); err != nil {
c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
return err
@ -650,7 +650,7 @@ func (c *Context) BindUri(obj interface{}) error {
// MustBindWith binds the passed struct pointer using the specified binding engine.
// It will abort the request with HTTP 400 if any error occurs.
// See the binding package.
func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error {
func (c *Context) MustBindWith(obj any, b binding.Binding) error {
if err := c.ShouldBindWith(obj, b); err != nil {
c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind) // nolint: errcheck
return err
@ -665,38 +665,38 @@ func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error {
// It parses the request's body as JSON if Content-Type == "application/json" using JSON or XML as a JSON input.
// It decodes the json payload into the struct specified as a pointer.
// Like c.Bind() but this method does not set the response status code to 400 or abort if input is not valid.
func (c *Context) ShouldBind(obj interface{}) error {
func (c *Context) ShouldBind(obj any) error {
b := binding.Default(c.Request.Method, c.ContentType())
return c.ShouldBindWith(obj, b)
}
// ShouldBindJSON is a shortcut for c.ShouldBindWith(obj, binding.JSON).
func (c *Context) ShouldBindJSON(obj interface{}) error {
func (c *Context) ShouldBindJSON(obj any) error {
return c.ShouldBindWith(obj, binding.JSON)
}
// ShouldBindXML is a shortcut for c.ShouldBindWith(obj, binding.XML).
func (c *Context) ShouldBindXML(obj interface{}) error {
func (c *Context) ShouldBindXML(obj any) error {
return c.ShouldBindWith(obj, binding.XML)
}
// ShouldBindQuery is a shortcut for c.ShouldBindWith(obj, binding.Query).
func (c *Context) ShouldBindQuery(obj interface{}) error {
func (c *Context) ShouldBindQuery(obj any) error {
return c.ShouldBindWith(obj, binding.Query)
}
// ShouldBindYAML is a shortcut for c.ShouldBindWith(obj, binding.YAML).
func (c *Context) ShouldBindYAML(obj interface{}) error {
func (c *Context) ShouldBindYAML(obj any) error {
return c.ShouldBindWith(obj, binding.YAML)
}
// ShouldBindHeader is a shortcut for c.ShouldBindWith(obj, binding.Header).
func (c *Context) ShouldBindHeader(obj interface{}) error {
func (c *Context) ShouldBindHeader(obj any) error {
return c.ShouldBindWith(obj, binding.Header)
}
// ShouldBindUri binds the passed struct pointer using the specified binding engine.
func (c *Context) ShouldBindUri(obj interface{}) error {
func (c *Context) ShouldBindUri(obj any) error {
m := make(map[string][]string)
for _, v := range c.Params {
m[v.Key] = []string{v.Value}
@ -706,7 +706,7 @@ func (c *Context) ShouldBindUri(obj interface{}) error {
// ShouldBindWith binds the passed struct pointer using the specified binding engine.
// See the binding package.
func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
func (c *Context) ShouldBindWith(obj any, b binding.Binding) error {
return b.Bind(c.Request, obj)
}
@ -715,7 +715,7 @@ func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error {
//
// NOTE: This method reads the body before binding. So you should use
// ShouldBindWith for better performance if you need to call only once.
func (c *Context) ShouldBindBodyWith(obj interface{}, bb binding.BindingBody) (err error) {
func (c *Context) ShouldBindBodyWith(obj any, bb binding.BindingBody) (err error) {
var body []byte
if cb, ok := c.Get(BodyBytesKey); ok {
if cbb, ok := cb.([]byte); ok {
@ -900,7 +900,7 @@ func (c *Context) Render(code int, r render.Render) {
// HTML renders the HTTP template specified by its file name.
// It also updates the HTTP code and sets the Content-Type as "text/html".
// See http://golang.org/doc/articles/wiki/
func (c *Context) HTML(code int, name string, obj interface{}) {
func (c *Context) HTML(code int, name string, obj any) {
instance := c.engine.HTMLRender.Instance(name, obj)
c.Render(code, instance)
}
@ -909,21 +909,21 @@ func (c *Context) HTML(code int, name string, obj interface{}) {
// It also sets the Content-Type as "application/json".
// WARNING: we recommend using this only for development purposes since printing pretty JSON is
// more CPU and bandwidth consuming. Use Context.JSON() instead.
func (c *Context) IndentedJSON(code int, obj interface{}) {
func (c *Context) IndentedJSON(code int, obj any) {
c.Render(code, render.IndentedJSON{Data: obj})
}
// SecureJSON serializes the given struct as Secure JSON into the response body.
// Default prepends "while(1)," to response body if the given struct is array values.
// It also sets the Content-Type as "application/json".
func (c *Context) SecureJSON(code int, obj interface{}) {
func (c *Context) SecureJSON(code int, obj any) {
c.Render(code, render.SecureJSON{Prefix: c.engine.secureJSONPrefix, Data: obj})
}
// JSONP serializes the given struct as JSON into the response body.
// It adds padding to response body to request data from a server residing in a different domain than the client.
// It also sets the Content-Type as "application/javascript".
func (c *Context) JSONP(code int, obj interface{}) {
func (c *Context) JSONP(code int, obj any) {
callback := c.DefaultQuery("callback", "")
if callback == "" {
c.Render(code, render.JSON{Data: obj})
@ -934,40 +934,40 @@ func (c *Context) JSONP(code int, obj interface{}) {
// JSON serializes the given struct as JSON into the response body.
// It also sets the Content-Type as "application/json".
func (c *Context) JSON(code int, obj interface{}) {
func (c *Context) JSON(code int, obj any) {
c.Render(code, render.JSON{Data: obj})
}
// AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string.
// It also sets the Content-Type as "application/json".
func (c *Context) AsciiJSON(code int, obj interface{}) {
func (c *Context) AsciiJSON(code int, obj any) {
c.Render(code, render.AsciiJSON{Data: obj})
}
// PureJSON serializes the given struct as JSON into the response body.
// PureJSON, unlike JSON, does not replace special html characters with their unicode entities.
func (c *Context) PureJSON(code int, obj interface{}) {
func (c *Context) PureJSON(code int, obj any) {
c.Render(code, render.PureJSON{Data: obj})
}
// XML serializes the given struct as XML into the response body.
// It also sets the Content-Type as "application/xml".
func (c *Context) XML(code int, obj interface{}) {
func (c *Context) XML(code int, obj any) {
c.Render(code, render.XML{Data: obj})
}
// YAML serializes the given struct as YAML into the response body.
func (c *Context) YAML(code int, obj interface{}) {
func (c *Context) YAML(code int, obj any) {
c.Render(code, render.YAML{Data: obj})
}
// ProtoBuf serializes the given struct as ProtoBuf into the response body.
func (c *Context) ProtoBuf(code int, obj interface{}) {
func (c *Context) ProtoBuf(code int, obj any) {
c.Render(code, render.ProtoBuf{Data: obj})
}
// String writes the given string into the response body.
func (c *Context) String(code int, format string, values ...interface{}) {
func (c *Context) String(code int, format string, values ...any) {
c.Render(code, render.String{Format: format, Data: values})
}
@ -1026,7 +1026,7 @@ func (c *Context) FileAttachment(filepath, filename string) {
}
// SSEvent writes a Server-Sent Event into the body stream.
func (c *Context) SSEvent(name string, message interface{}) {
func (c *Context) SSEvent(name string, message any) {
c.Render(-1, sse.Event{
Event: name,
Data: message,
@ -1060,11 +1060,11 @@ func (c *Context) Stream(step func(w io.Writer) bool) bool {
type Negotiate struct {
Offered []string
HTMLName string
HTMLData interface{}
JSONData interface{}
XMLData interface{}
YAMLData interface{}
Data interface{}
HTMLData any
JSONData any
XMLData any
YAMLData any
Data any
}
// Negotiate calls different Render according to acceptable Accept format.
@ -1158,7 +1158,7 @@ func (c *Context) Err() error {
// Value returns the value associated with this context for key, or nil
// if no value is associated with key. Successive calls to Value with
// the same key returns the same result.
func (c *Context) Value(key interface{}) interface{} {
func (c *Context) Value(key any) any {
if key == 0 {
return c.Request
}

View File

@ -212,7 +212,7 @@ func TestContextSetGetValues(t *testing.T) {
c.Set("uint64", uint64(42))
c.Set("float32", float32(4.2))
c.Set("float64", 4.2)
var a interface{} = 1
var a any = 1
c.Set("intInterface", a)
assert.Exactly(t, c.MustGet("string").(string), "this is a string")
@ -287,7 +287,7 @@ func TestContextGetStringSlice(t *testing.T) {
func TestContextGetStringMap(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
m := make(map[string]interface{})
m := make(map[string]any)
m["foo"] = 1
c.Set("map", m)
@ -2125,12 +2125,12 @@ type contextKey string
func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
tests := []struct {
name string
getContextAndKey func() (*Context, interface{})
value interface{}
getContextAndKey func() (*Context, any)
value any
}{
{
name: "c with struct context key",
getContextAndKey: func() (*Context, interface{}) {
getContextAndKey: func() (*Context, any) {
var key struct{}
c := &Context{}
c.Request, _ = http.NewRequest("POST", "/", nil)
@ -2141,7 +2141,7 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
},
{
name: "c with string context key",
getContextAndKey: func() (*Context, interface{}) {
getContextAndKey: func() (*Context, any) {
c := &Context{}
c.Request, _ = http.NewRequest("POST", "/", nil)
c.Request = c.Request.WithContext(context.WithValue(context.TODO(), contextKey("key"), "value"))
@ -2151,7 +2151,7 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
},
{
name: "c with nil http.Request",
getContextAndKey: func() (*Context, interface{}) {
getContextAndKey: func() (*Context, any) {
c := &Context{}
return c, "key"
},
@ -2159,7 +2159,7 @@ func TestContextWithFallbackValueFromRequestContext(t *testing.T) {
},
{
name: "c with nil http.Request.Context()",
getContextAndKey: func() (*Context, interface{}) {
getContextAndKey: func() (*Context, any) {
c := &Context{}
c.Request, _ = http.NewRequest("POST", "/", nil)
return c, "key"

View File

@ -47,7 +47,7 @@ func debugPrintLoadTemplate(tmpl *template.Template) {
}
}
func debugPrint(format string, values ...interface{}) {
func debugPrint(format string, values ...any) {
if IsDebugging() {
if !strings.HasSuffix(format, "\n") {
format += "\n"

View File

@ -12,7 +12,7 @@ import (
// BindWith binds the passed struct pointer using the specified binding engine.
// See the binding package.
func (c *Context) BindWith(obj interface{}, b binding.Binding) error {
func (c *Context) BindWith(obj any, b binding.Binding) error {
log.Println(`BindWith(\"interface{}, binding.Binding\") error is going to
be deprecated, please check issue #662 and either use MustBindWith() if you
want HTTP 400 to be automatically returned if any error occur, or use

View File

@ -34,7 +34,7 @@ const (
type Error struct {
Err error
Type ErrorType
Meta interface{}
Meta any
}
type errorMsgs []*Error
@ -48,13 +48,13 @@ func (msg *Error) SetType(flags ErrorType) *Error {
}
// SetMeta sets the error's meta data.
func (msg *Error) SetMeta(data interface{}) *Error {
func (msg *Error) SetMeta(data any) *Error {
msg.Meta = data
return msg
}
// JSON creates a properly formatted JSON
func (msg *Error) JSON() interface{} {
func (msg *Error) JSON() any {
jsonData := H{}
if msg.Meta != nil {
value := reflect.ValueOf(msg.Meta)
@ -139,14 +139,14 @@ func (a errorMsgs) Errors() []string {
return errorStrings
}
func (a errorMsgs) JSON() interface{} {
func (a errorMsgs) JSON() any {
switch length := len(a); length {
case 0:
return nil
case 1:
return a.Last().JSON()
default:
jsonData := make([]interface{}, length)
jsonData := make([]any, length)
for i, err := range a {
jsonData[i] = err.JSON()
}

View File

@ -86,7 +86,7 @@ Error #02: second
Error #03: third
Meta: map[status:400]
`, errs.String())
assert.Equal(t, []interface{}{
assert.Equal(t, []any{
H{"error": "first"},
H{"error": "second", "meta": "some data"},
H{"error": "third", "status": "400"},

2
gin.go
View File

@ -198,7 +198,7 @@ func New() *Engine {
trustedCIDRs: defaultTrustedCIDRs,
}
engine.RouterGroup.engine = engine
engine.pool.New = func() interface{} {
engine.pool.New = func() any {
return engine.allocateContext()
}
return engine

View File

@ -43,7 +43,7 @@ func setupHTMLFiles(t *testing.T, mode string, tls bool, loadMethod func(*Engine
c.HTML(http.StatusOK, "hello.tmpl", map[string]string{"name": "world"})
})
router.GET("/raw", func(c *Context) {
c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
c.HTML(http.StatusOK, "raw.tmpl", map[string]any{
"now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
})
})
@ -467,7 +467,7 @@ func TestNoMethodWithGlobalHandlers(t *testing.T) {
compareFunc(t, router.allNoMethod[2], middleware0)
}
func compareFunc(t *testing.T, a, b interface{}) {
func compareFunc(t *testing.T, a, b any) {
sf1 := reflect.ValueOf(a)
sf2 := reflect.ValueOf(b)
if sf1.Pointer() != sf2.Pointer() {

View File

@ -75,7 +75,7 @@ type LogFormatterParams struct {
// BodySize is the size of the Response Body
BodySize int
// Keys are the keys set on the request's context.
Keys map[string]interface{}
Keys map[string]any
}
// StatusCodeColor is the ANSI color for appropriately logging http status code to a terminal.

View File

@ -181,7 +181,7 @@ func TestLoggerWithFormatter(t *testing.T) {
func TestLoggerWithConfigFormatting(t *testing.T) {
var gotParam LogFormatterParams
var gotKeys map[string]interface{}
var gotKeys map[string]any
buffer := new(bytes.Buffer)
router := New()

View File

@ -28,7 +28,7 @@ var (
)
// RecoveryFunc defines the function passable to CustomRecovery.
type RecoveryFunc func(c *Context, err interface{})
type RecoveryFunc func(c *Context, err any)
// Recovery returns a middleware that recovers from any panics and writes a 500 if there was one.
func Recovery() HandlerFunc {
@ -102,7 +102,7 @@ func CustomRecoveryWithWriter(out io.Writer, handle RecoveryFunc) HandlerFunc {
}
}
func defaultHandleRecovery(c *Context, err interface{}) {
func defaultHandleRecovery(c *Context, err any) {
c.AbortWithStatus(http.StatusInternalServerError)
}

View File

@ -148,7 +148,7 @@ func TestCustomRecoveryWithWriter(t *testing.T) {
errBuffer := new(bytes.Buffer)
buffer := new(bytes.Buffer)
router := New()
handleRecovery := func(c *Context, err interface{}) {
handleRecovery := func(c *Context, err any) {
errBuffer.WriteString(err.(string))
c.AbortWithStatus(http.StatusBadRequest)
}
@ -183,7 +183,7 @@ func TestCustomRecovery(t *testing.T) {
buffer := new(bytes.Buffer)
router := New()
DefaultErrorWriter = buffer
handleRecovery := func(c *Context, err interface{}) {
handleRecovery := func(c *Context, err any) {
errBuffer.WriteString(err.(string))
c.AbortWithStatus(http.StatusBadRequest)
}
@ -218,7 +218,7 @@ func TestRecoveryWithWriterWithCustomRecovery(t *testing.T) {
buffer := new(bytes.Buffer)
router := New()
DefaultErrorWriter = buffer
handleRecovery := func(c *Context, err interface{}) {
handleRecovery := func(c *Context, err any) {
errBuffer.WriteString(err.(string))
c.AbortWithStatus(http.StatusBadRequest)
}

10
render/any.go Normal file
View File

@ -0,0 +1,10 @@
// Copyright 2021 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
//go:build !go1.18
// +build !go1.18
package render
type any = interface{}

View File

@ -20,7 +20,7 @@ type Delims struct {
// HTMLRender interface is to be implemented by HTMLProduction and HTMLDebug.
type HTMLRender interface {
// Instance returns an HTML instance.
Instance(string, interface{}) Render
Instance(string, any) Render
}
// HTMLProduction contains template reference and its delims.
@ -41,13 +41,13 @@ type HTMLDebug struct {
type HTML struct {
Template *template.Template
Name string
Data interface{}
Data any
}
var htmlContentType = []string{"text/html; charset=utf-8"}
// Instance (HTMLProduction) returns an HTML instance which it realizes Render interface.
func (r HTMLProduction) Instance(name string, data interface{}) Render {
func (r HTMLProduction) Instance(name string, data any) Render {
return HTML{
Template: r.Template,
Name: name,
@ -56,7 +56,7 @@ func (r HTMLProduction) Instance(name string, data interface{}) Render {
}
// Instance (HTMLDebug) returns an HTML instance which it realizes Render interface.
func (r HTMLDebug) Instance(name string, data interface{}) Render {
func (r HTMLDebug) Instance(name string, data any) Render {
return HTML{
Template: r.loadTemplate(),
Name: name,

View File

@ -16,34 +16,34 @@ import (
// JSON contains the given interface object.
type JSON struct {
Data interface{}
Data any
}
// IndentedJSON contains the given interface object.
type IndentedJSON struct {
Data interface{}
Data any
}
// SecureJSON contains the given interface object and its prefix.
type SecureJSON struct {
Prefix string
Data interface{}
Data any
}
// JsonpJSON contains the given interface object its callback.
type JsonpJSON struct {
Callback string
Data interface{}
Data any
}
// AsciiJSON contains the given interface object.
type AsciiJSON struct {
Data interface{}
Data any
}
// PureJSON contains the given interface object.
type PureJSON struct {
Data interface{}
Data any
}
var (
@ -66,7 +66,7 @@ func (r JSON) WriteContentType(w http.ResponseWriter) {
}
// WriteJSON marshals the given interface object and writes it with custom ContentType.
func WriteJSON(w http.ResponseWriter, obj interface{}) error {
func WriteJSON(w http.ResponseWriter, obj any) error {
writeContentType(w, jsonContentType)
jsonBytes, err := json.Marshal(obj)
if err != nil {

View File

@ -21,7 +21,7 @@ var (
// MsgPack contains the given interface object.
type MsgPack struct {
Data interface{}
Data any
}
var msgpackContentType = []string{"application/msgpack; charset=utf-8"}
@ -37,7 +37,7 @@ func (r MsgPack) Render(w http.ResponseWriter) error {
}
// WriteMsgPack writes MsgPack ContentType and encodes the given interface object.
func WriteMsgPack(w http.ResponseWriter, obj interface{}) error {
func WriteMsgPack(w http.ResponseWriter, obj any) error {
writeContentType(w, msgpackContentType)
var mh codec.MsgpackHandle
return codec.NewEncoder(w, &mh).Encode(obj)

View File

@ -12,7 +12,7 @@ import (
// ProtoBuf contains the given interface object.
type ProtoBuf struct {
Data interface{}
Data any
}
var protobufContentType = []string{"application/x-protobuf"}

View File

@ -21,7 +21,7 @@ import (
func TestRenderMsgPack(t *testing.T) {
w := httptest.NewRecorder()
data := map[string]interface{}{
data := map[string]any{
"foo": "bar",
}

View File

@ -24,7 +24,7 @@ import (
func TestRenderJSON(t *testing.T) {
w := httptest.NewRecorder()
data := map[string]interface{}{
data := map[string]any{
"foo": "bar",
"html": "<b>",
}
@ -49,7 +49,7 @@ func TestRenderJSONPanics(t *testing.T) {
func TestRenderIndentedJSON(t *testing.T) {
w := httptest.NewRecorder()
data := map[string]interface{}{
data := map[string]any{
"foo": "bar",
"bar": "foo",
}
@ -72,7 +72,7 @@ func TestRenderIndentedJSONPanics(t *testing.T) {
func TestRenderSecureJSON(t *testing.T) {
w1 := httptest.NewRecorder()
data := map[string]interface{}{
data := map[string]any{
"foo": "bar",
}
@ -86,7 +86,7 @@ func TestRenderSecureJSON(t *testing.T) {
assert.Equal(t, "application/json; charset=utf-8", w1.Header().Get("Content-Type"))
w2 := httptest.NewRecorder()
datas := []map[string]interface{}{{
datas := []map[string]any{{
"foo": "bar",
}, {
"bar": "foo",
@ -109,7 +109,7 @@ func TestRenderSecureJSONFail(t *testing.T) {
func TestRenderJsonpJSON(t *testing.T) {
w1 := httptest.NewRecorder()
data := map[string]interface{}{
data := map[string]any{
"foo": "bar",
}
@ -123,7 +123,7 @@ func TestRenderJsonpJSON(t *testing.T) {
assert.Equal(t, "application/javascript; charset=utf-8", w1.Header().Get("Content-Type"))
w2 := httptest.NewRecorder()
datas := []map[string]interface{}{{
datas := []map[string]any{{
"foo": "bar",
}, {
"bar": "foo",
@ -137,7 +137,7 @@ func TestRenderJsonpJSON(t *testing.T) {
func TestRenderJsonpJSONError2(t *testing.T) {
w := httptest.NewRecorder()
data := map[string]interface{}{
data := map[string]any{
"foo": "bar",
}
(JsonpJSON{"", data}).WriteContentType(w)
@ -161,7 +161,7 @@ func TestRenderJsonpJSONFail(t *testing.T) {
func TestRenderAsciiJSON(t *testing.T) {
w1 := httptest.NewRecorder()
data1 := map[string]interface{}{
data1 := map[string]any{
"lang": "GO语言",
"tag": "<br>",
}
@ -190,7 +190,7 @@ func TestRenderAsciiJSONFail(t *testing.T) {
func TestRenderPureJSON(t *testing.T) {
w := httptest.NewRecorder()
data := map[string]interface{}{
data := map[string]any{
"foo": "bar",
"html": "<b>",
}
@ -200,7 +200,7 @@ func TestRenderPureJSON(t *testing.T) {
assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
}
type xmlmap map[string]interface{}
type xmlmap map[string]any
// Allows type H to be used with xml.Marshal
func (h xmlmap) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
@ -244,7 +244,7 @@ b:
type fail struct{}
// Hook MarshalYAML
func (ft *fail) MarshalYAML() (interface{}, error) {
func (ft *fail) MarshalYAML() (any, error) {
return nil, errors.New("fail")
}
@ -358,13 +358,13 @@ func TestRenderString(t *testing.T) {
(String{
Format: "hello %s %d",
Data: []interface{}{},
Data: []any{},
}).WriteContentType(w)
assert.Equal(t, "text/plain; charset=utf-8", w.Header().Get("Content-Type"))
err := (String{
Format: "hola %s %d",
Data: []interface{}{"manu", 2},
Data: []any{"manu", 2},
}).Render(w)
assert.NoError(t, err)
@ -377,7 +377,7 @@ func TestRenderStringLenZero(t *testing.T) {
err := (String{
Format: "hola %s %d",
Data: []interface{}{},
Data: []any{},
}).Render(w)
assert.NoError(t, err)
@ -390,7 +390,7 @@ func TestRenderHTMLTemplate(t *testing.T) {
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
htmlRender := HTMLProduction{Template: templ}
instance := htmlRender.Instance("t", map[string]interface{}{
instance := htmlRender.Instance("t", map[string]any{
"name": "alexandernyquist",
})
@ -406,7 +406,7 @@ func TestRenderHTMLTemplateEmptyName(t *testing.T) {
templ := template.Must(template.New("").Parse(`Hello {{.name}}`))
htmlRender := HTMLProduction{Template: templ}
instance := htmlRender.Instance("", map[string]interface{}{
instance := htmlRender.Instance("", map[string]any{
"name": "alexandernyquist",
})
@ -425,7 +425,7 @@ func TestRenderHTMLDebugFiles(t *testing.T) {
Delims: Delims{Left: "{[{", Right: "}]}"},
FuncMap: nil,
}
instance := htmlRender.Instance("hello.tmpl", map[string]interface{}{
instance := htmlRender.Instance("hello.tmpl", map[string]any{
"name": "thinkerou",
})
@ -444,7 +444,7 @@ func TestRenderHTMLDebugGlob(t *testing.T) {
Delims: Delims{Left: "{[{", Right: "}]}"},
FuncMap: nil,
}
instance := htmlRender.Instance("hello.tmpl", map[string]interface{}{
instance := htmlRender.Instance("hello.tmpl", map[string]any{
"name": "thinkerou",
})

View File

@ -14,7 +14,7 @@ import (
// String contains the given interface object slice and its format.
type String struct {
Format string
Data []interface{}
Data []any
}
var plainContentType = []string{"text/plain; charset=utf-8"}
@ -30,7 +30,7 @@ func (r String) WriteContentType(w http.ResponseWriter) {
}
// WriteString writes data according to its format and write custom ContentType.
func WriteString(w http.ResponseWriter, format string, data []interface{}) (err error) {
func WriteString(w http.ResponseWriter, format string, data []any) (err error) {
writeContentType(w, plainContentType)
if len(data) > 0 {
_, err = fmt.Fprintf(w, format, data...)

View File

@ -11,7 +11,7 @@ import (
// XML contains the given interface object.
type XML struct {
Data interface{}
Data any
}
var xmlContentType = []string{"application/xml; charset=utf-8"}

View File

@ -12,7 +12,7 @@ import (
// YAML contains the given interface object.
type YAML struct {
Data interface{}
Data any
}
var yamlContentType = []string{"application/x-yaml; charset=utf-8"}

10
testdata/protoexample/any.go vendored Normal file
View File

@ -0,0 +1,10 @@
// Copyright 2021 Gin Core Team. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
//go:build !go1.18
// +build !go1.18
package protoexample
type any = interface{}

View File

@ -231,7 +231,7 @@ func file_test_proto_rawDescGZIP() []byte {
var file_test_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_test_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_test_proto_goTypes = []interface{}{
var file_test_proto_goTypes = []any{
(FOO)(0), // 0: protoexample.FOO
(*Test)(nil), // 1: protoexample.Test
(*Test_OptionalGroup)(nil), // 2: protoexample.Test.OptionalGroup
@ -251,7 +251,7 @@ func file_test_proto_init() {
return
}
if !protoimpl.UnsafeEnabled {
file_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
file_test_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*Test); i {
case 0:
return &v.state
@ -263,7 +263,7 @@ func file_test_proto_init() {
return nil
}
}
file_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
file_test_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*Test_OptionalGroup); i {
case 0:
return &v.state

View File

@ -357,7 +357,7 @@ func TestUnescapeParameters(t *testing.T) {
checkPriorities(t, tree)
}
func catchPanic(testFunc func()) (recv interface{}) {
func catchPanic(testFunc func()) (recv any) {
defer func() {
recv = recover()
}()

View File

@ -19,7 +19,7 @@ import (
const BindKey = "_gin-gonic/gin/bindkey"
// Bind is a helper function for given interface object and returns a Gin middleware.
func Bind(val interface{}) HandlerFunc {
func Bind(val any) HandlerFunc {
value := reflect.ValueOf(val)
if value.Kind() == reflect.Ptr {
panic(`Bind struct can not be a pointer. Example:
@ -51,7 +51,7 @@ func WrapH(h http.Handler) HandlerFunc {
}
// H is a shortcut for map[string]interface{}
type H map[string]interface{}
type H map[string]any
// MarshalXML allows type H to be used with xml.Marshal.
func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
@ -90,7 +90,7 @@ func filterFlags(content string) string {
return content
}
func chooseData(custom, wildcard interface{}) interface{} {
func chooseData(custom, wildcard any) any {
if custom != nil {
return custom
}
@ -121,7 +121,7 @@ func lastChar(str string) uint8 {
return str[len(str)-1]
}
func nameOfFunction(f interface{}) string {
func nameOfFunction(f any) string {
return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
}