Skip to content

replace interface{} → any #2631

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
replace: interface{} → any
n9te9 committed Jun 24, 2024
commit 81bb9d86bbf63c573cde1642593996f8d92a7396
16 changes: 8 additions & 8 deletions bind.go
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ import (

// Binder is the interface that wraps the Bind method.
type Binder interface {
Bind(i interface{}, c Context) error
Bind(i any, c Context) error
}

// DefaultBinder is the default implementation of the Binder interface.
@@ -38,7 +38,7 @@ type bindMultipleUnmarshaler interface {
}

// BindPathParams binds path params to bindable object
func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error {
func (b *DefaultBinder) BindPathParams(c Context, i any) error {
names := c.ParamNames()
values := c.ParamValues()
params := map[string][]string{}
@@ -52,7 +52,7 @@ func (b *DefaultBinder) BindPathParams(c Context, i interface{}) error {
}

// BindQueryParams binds query params to bindable object
func (b *DefaultBinder) BindQueryParams(c Context, i interface{}) error {
func (b *DefaultBinder) BindQueryParams(c Context, i any) error {
if err := b.bindData(i, c.QueryParams(), "query"); err != nil {
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
}
@@ -64,7 +64,7 @@ func (b *DefaultBinder) BindQueryParams(c Context, i interface{}) error {
// which parses form data from BOTH URL and BODY if content type is not MIMEMultipartForm
// See non-MIMEMultipartForm: https://golang.org/pkg/net/http/#Request.ParseForm
// See MIMEMultipartForm: https://golang.org/pkg/net/http/#Request.ParseMultipartForm
func (b *DefaultBinder) BindBody(c Context, i interface{}) (err error) {
func (b *DefaultBinder) BindBody(c Context, i any) (err error) {
req := c.Request()
if req.ContentLength == 0 {
return
@@ -105,7 +105,7 @@ func (b *DefaultBinder) BindBody(c Context, i interface{}) (err error) {
}

// BindHeaders binds HTTP headers to a bindable object
func (b *DefaultBinder) BindHeaders(c Context, i interface{}) error {
func (b *DefaultBinder) BindHeaders(c Context, i any) error {
if err := b.bindData(i, c.Request().Header, "header"); err != nil {
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
}
@@ -115,7 +115,7 @@ func (b *DefaultBinder) BindHeaders(c Context, i interface{}) error {
// Bind implements the `Binder#Bind` function.
// Binding is done in following order: 1) path params; 2) query params; 3) request body. Each step COULD override previous
// step binded values. For single source binding use their own methods BindBody, BindQueryParams, BindPathParams.
func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
func (b *DefaultBinder) Bind(i any, c Context) (err error) {
if err := b.BindPathParams(c, i); err != nil {
return err
}
@@ -132,7 +132,7 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
}

// bindData will bind data ONLY fields in destination struct that have EXPLICIT tag
func (b *DefaultBinder) bindData(destination interface{}, data map[string][]string, tag string) error {
func (b *DefaultBinder) bindData(destination any, data map[string][]string, tag string) error {
if destination == nil || len(data) == 0 {
return nil
}
@@ -142,7 +142,7 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
// Support binding to limited Map destinations:
// - map[string][]string,
// - map[string]string <-- (binds first value from data slice)
// - map[string]interface{}
// - map[string]any
// You are better off binding to struct but there are user who want this map feature. Source of data for these cases are:
// params,query,header,form as these sources produce string values, most of the time slice of strings, actually.
if typ.Kind() == reflect.Map && typ.Key().Kind() == reflect.String {
20 changes: 10 additions & 10 deletions bind_test.go
Original file line number Diff line number Diff line change
@@ -493,10 +493,10 @@ func TestDefaultBinder_bindDataToMap(t *testing.T) {
})

t.Run("ok, bind to map[string]interface", func(t *testing.T) {
dest := map[string]interface{}{}
dest := map[string]any{}
assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
assert.Equal(t,
map[string]interface{}{
map[string]any{
"multiple": []string{"1", "2"},
"single": []string{"3"},
},
@@ -505,10 +505,10 @@ func TestDefaultBinder_bindDataToMap(t *testing.T) {
})

t.Run("ok, bind to map[string]interface with nil map", func(t *testing.T) {
var dest map[string]interface{}
var dest map[string]any
assert.NoError(t, new(DefaultBinder).bindData(&dest, exampleData, "param"))
assert.Equal(t,
map[string]interface{}{
map[string]any{
"multiple": []string{"1", "2"},
"single": []string{"3"},
},
@@ -767,9 +767,9 @@ func TestDefaultBinder_BindToStructFromMixedSources(t *testing.T) {
givenURL string
givenContent io.Reader
givenMethod string
whenBindTarget interface{}
whenBindTarget any
whenNoPathParams bool
expect interface{}
expect any
expectError string
}{
{
@@ -902,7 +902,7 @@ func TestDefaultBinder_BindToStructFromMixedSources(t *testing.T) {
c.SetParamValues("node_from_path")
}

var bindTarget interface{}
var bindTarget any
if tc.whenBindTarget != nil {
bindTarget = tc.whenBindTarget
} else {
@@ -941,8 +941,8 @@ func TestDefaultBinder_BindBody(t *testing.T) {
givenMethod string
givenContentType string
whenNoPathParams bool
whenBindTarget interface{}
expect interface{}
whenBindTarget any
expect any
expectError string
}{
{
@@ -1083,7 +1083,7 @@ func TestDefaultBinder_BindBody(t *testing.T) {
c.SetParamValues("real_node")
}

var bindTarget interface{}
var bindTarget any
if tc.whenBindTarget != nil {
bindTarget = tc.whenBindTarget
} else {
34 changes: 17 additions & 17 deletions binder.go
Original file line number Diff line number Diff line change
@@ -75,7 +75,7 @@ type BindingError struct {
}

// NewBindingError creates new instance of binding error
func NewBindingError(sourceParam string, values []string, message interface{}, internalError error) error {
func NewBindingError(sourceParam string, values []string, message any, internalError error) error {
return &BindingError{
Field: sourceParam,
Values: values,
@@ -99,7 +99,7 @@ type ValueBinder struct {
// ValuesFunc is used to get all values for parameter from request. i.e. `/api/search?ids=1&ids=2`
ValuesFunc func(sourceParam string) []string
// ErrorFunc is used to create errors. Allows you to use your own error type, that for example marshals to your specific json response
ErrorFunc func(sourceParam string, values []string, message interface{}, internalError error) error
ErrorFunc func(sourceParam string, values []string, message any, internalError error) error
errors []error
// failFast is flag for binding methods to return without attempting to bind when previous binding already failed
failFast bool
@@ -402,17 +402,17 @@ func (b *ValueBinder) MustTextUnmarshaler(sourceParam string, dest encoding.Text

// BindWithDelimiter binds parameter to destination by suitable conversion function.
// Delimiter is used before conversion to split parameter value to separate values
func (b *ValueBinder) BindWithDelimiter(sourceParam string, dest interface{}, delimiter string) *ValueBinder {
func (b *ValueBinder) BindWithDelimiter(sourceParam string, dest any, delimiter string) *ValueBinder {
return b.bindWithDelimiter(sourceParam, dest, delimiter, false)
}

// MustBindWithDelimiter requires parameter value to exist to bind destination by suitable conversion function.
// Delimiter is used before conversion to split parameter value to separate values
func (b *ValueBinder) MustBindWithDelimiter(sourceParam string, dest interface{}, delimiter string) *ValueBinder {
func (b *ValueBinder) MustBindWithDelimiter(sourceParam string, dest any, delimiter string) *ValueBinder {
return b.bindWithDelimiter(sourceParam, dest, delimiter, true)
}

func (b *ValueBinder) bindWithDelimiter(sourceParam string, dest interface{}, delimiter string, valueMustExist bool) *ValueBinder {
func (b *ValueBinder) bindWithDelimiter(sourceParam string, dest any, delimiter string, valueMustExist bool) *ValueBinder {
if b.failFast && b.errors != nil {
return b
}
@@ -500,7 +500,7 @@ func (b *ValueBinder) MustInt(sourceParam string, dest *int) *ValueBinder {
return b.intValue(sourceParam, dest, 0, true)
}

func (b *ValueBinder) intValue(sourceParam string, dest interface{}, bitSize int, valueMustExist bool) *ValueBinder {
func (b *ValueBinder) intValue(sourceParam string, dest any, bitSize int, valueMustExist bool) *ValueBinder {
if b.failFast && b.errors != nil {
return b
}
@@ -516,7 +516,7 @@ func (b *ValueBinder) intValue(sourceParam string, dest interface{}, bitSize int
return b.int(sourceParam, value, dest, bitSize)
}

func (b *ValueBinder) int(sourceParam string, value string, dest interface{}, bitSize int) *ValueBinder {
func (b *ValueBinder) int(sourceParam string, value string, dest any, bitSize int) *ValueBinder {
n, err := strconv.ParseInt(value, 10, bitSize)
if err != nil {
if bitSize == 0 {
@@ -542,7 +542,7 @@ func (b *ValueBinder) int(sourceParam string, value string, dest interface{}, bi
return b
}

func (b *ValueBinder) intsValue(sourceParam string, dest interface{}, valueMustExist bool) *ValueBinder {
func (b *ValueBinder) intsValue(sourceParam string, dest any, valueMustExist bool) *ValueBinder {
if b.failFast && b.errors != nil {
return b
}
@@ -557,7 +557,7 @@ func (b *ValueBinder) intsValue(sourceParam string, dest interface{}, valueMustE
return b.ints(sourceParam, values, dest)
}

func (b *ValueBinder) ints(sourceParam string, values []string, dest interface{}) *ValueBinder {
func (b *ValueBinder) ints(sourceParam string, values []string, dest any) *ValueBinder {
switch d := dest.(type) {
case *[]int64:
tmp := make([]int64, len(values))
@@ -728,7 +728,7 @@ func (b *ValueBinder) MustUint(sourceParam string, dest *uint) *ValueBinder {
return b.uintValue(sourceParam, dest, 0, true)
}

func (b *ValueBinder) uintValue(sourceParam string, dest interface{}, bitSize int, valueMustExist bool) *ValueBinder {
func (b *ValueBinder) uintValue(sourceParam string, dest any, bitSize int, valueMustExist bool) *ValueBinder {
if b.failFast && b.errors != nil {
return b
}
@@ -744,7 +744,7 @@ func (b *ValueBinder) uintValue(sourceParam string, dest interface{}, bitSize in
return b.uint(sourceParam, value, dest, bitSize)
}

func (b *ValueBinder) uint(sourceParam string, value string, dest interface{}, bitSize int) *ValueBinder {
func (b *ValueBinder) uint(sourceParam string, value string, dest any, bitSize int) *ValueBinder {
n, err := strconv.ParseUint(value, 10, bitSize)
if err != nil {
if bitSize == 0 {
@@ -770,7 +770,7 @@ func (b *ValueBinder) uint(sourceParam string, value string, dest interface{}, b
return b
}

func (b *ValueBinder) uintsValue(sourceParam string, dest interface{}, valueMustExist bool) *ValueBinder {
func (b *ValueBinder) uintsValue(sourceParam string, dest any, valueMustExist bool) *ValueBinder {
if b.failFast && b.errors != nil {
return b
}
@@ -785,7 +785,7 @@ func (b *ValueBinder) uintsValue(sourceParam string, dest interface{}, valueMust
return b.uints(sourceParam, values, dest)
}

func (b *ValueBinder) uints(sourceParam string, values []string, dest interface{}) *ValueBinder {
func (b *ValueBinder) uints(sourceParam string, values []string, dest any) *ValueBinder {
switch d := dest.(type) {
case *[]uint64:
tmp := make([]uint64, len(values))
@@ -991,7 +991,7 @@ func (b *ValueBinder) MustFloat32(sourceParam string, dest *float32) *ValueBinde
return b.floatValue(sourceParam, dest, 32, true)
}

func (b *ValueBinder) floatValue(sourceParam string, dest interface{}, bitSize int, valueMustExist bool) *ValueBinder {
func (b *ValueBinder) floatValue(sourceParam string, dest any, bitSize int, valueMustExist bool) *ValueBinder {
if b.failFast && b.errors != nil {
return b
}
@@ -1007,7 +1007,7 @@ func (b *ValueBinder) floatValue(sourceParam string, dest interface{}, bitSize i
return b.float(sourceParam, value, dest, bitSize)
}

func (b *ValueBinder) float(sourceParam string, value string, dest interface{}, bitSize int) *ValueBinder {
func (b *ValueBinder) float(sourceParam string, value string, dest any, bitSize int) *ValueBinder {
n, err := strconv.ParseFloat(value, bitSize)
if err != nil {
b.setError(b.ErrorFunc(sourceParam, []string{value}, fmt.Sprintf("failed to bind field value to float%v", bitSize), err))
@@ -1023,7 +1023,7 @@ func (b *ValueBinder) float(sourceParam string, value string, dest interface{},
return b
}

func (b *ValueBinder) floatsValue(sourceParam string, dest interface{}, valueMustExist bool) *ValueBinder {
func (b *ValueBinder) floatsValue(sourceParam string, dest any, valueMustExist bool) *ValueBinder {
if b.failFast && b.errors != nil {
return b
}
@@ -1038,7 +1038,7 @@ func (b *ValueBinder) floatsValue(sourceParam string, dest interface{}, valueMus
return b.floats(sourceParam, values, dest)
}

func (b *ValueBinder) floats(sourceParam string, values []string, dest interface{}) *ValueBinder {
func (b *ValueBinder) floats(sourceParam string, values []string, dest any) *ValueBinder {
switch d := dest.(type) {
case *[]float64:
tmp := make([]float64, len(values))
9 changes: 5 additions & 4 deletions binder_test.go
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/stretchr/testify/assert"
"io"
"math/big"
"net/http"
@@ -16,6 +15,8 @@ import (
"strings"
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func createTestContext(URL string, body io.Reader, pathParams map[string]string) Context {
@@ -271,7 +272,7 @@ func TestValueBinder_CustomFunc(t *testing.T) {
givenFuncErrors []error
whenURL string
expectParamValues []string
expectValue interface{}
expectValue any
expectErrors []string
}{
{
@@ -346,7 +347,7 @@ func TestValueBinder_MustCustomFunc(t *testing.T) {
givenFuncErrors []error
whenURL string
expectParamValues []string
expectValue interface{}
expectValue any
expectErrors []string
}{
{
@@ -2376,7 +2377,7 @@ func TestValueBinder_BindWithDelimiter_types(t *testing.T) {
var testCases = []struct {
name string
whenURL string
expect interface{}
expect any
}{
{
name: "ok, strings",
Loading