1
0
mirror of https://github.com/kataras/iris.git synced 2025-12-18 10:27:06 +00:00

Update to Version 8.4.2 | Read HISTORY.md

https://github.com/kataras/iris/blob/master/HISTORY.md#fr-15-september-2017--v842

Former-commit-id: 0ee4cc1d93ef7f26e5d402fdfbe07062aff5b08c
This commit is contained in:
Gerasimos (Makis) Maropoulos
2017-09-15 15:05:35 +03:00
parent 1c512619c7
commit 69b5327ecc
14 changed files with 382 additions and 192 deletions

View File

@@ -1,68 +1,62 @@
package methodfunc
import (
"reflect"
"github.com/kataras/iris/context"
)
// FuncCaller is responsible to call the controller's function
// which is responsible
// for that request for this http method.
type FuncCaller interface {
// MethodCall fires the actual handler.
// The "ctx" is the current context, helps us to get any path parameter's values.
//
// The "f" is the controller's function which is responsible
// for that request for this http method.
// That function can accept one parameter.
//
// The default callers (and the only one for now)
// are pre-calculated by the framework.
MethodCall(ctx context.Context, f interface{})
}
// buildMethodCall builds the method caller.
// We have repeated code here but it's the only way
// to support more than one input arguments without performance cost compared to previous implementation.
// so it's hard-coded written to check the length of input args and their types.
func buildMethodCall(a *ast) func(ctx context.Context, f reflect.Value) {
// if accepts one or more parameters.
if a.dynamic {
// if one function input argument then call the function
// by "casting" (faster).
if l := len(a.paramKeys); l == 1 {
paramType := a.paramTypes[0]
paramKey := a.paramKeys[0]
type callerFunc func(ctx context.Context, f interface{})
if paramType == paramTypeInt {
return func(ctx context.Context, f reflect.Value) {
v, _ := ctx.Params().GetInt(paramKey)
f.Interface().(func(int))(v)
}
}
func (c callerFunc) MethodCall(ctx context.Context, f interface{}) {
c(ctx, f)
}
if paramType == paramTypeLong {
return func(ctx context.Context, f reflect.Value) {
v, _ := ctx.Params().GetInt64(paramKey)
f.Interface().(func(int64))(v)
}
func resolveCaller(p pathInfo) callerFunc {
// if it's standard `Get`, `Post` without parameters.
if p.ParamType == "" {
return func(ctx context.Context, f interface{}) {
f.(func())()
}
if paramType == paramTypeBoolean {
return func(ctx context.Context, f reflect.Value) {
v, _ := ctx.Params().GetBool(paramKey)
f.Interface().(func(bool))(v)
}
}
// string, path...
return func(ctx context.Context, f reflect.Value) {
f.Interface().(func(string))(ctx.Params().Get(paramKey))
}
}
// if func input arguments are more than one then
// use the Call method (slower).
return func(ctx context.Context, f reflect.Value) {
f.Call(a.paramValues(ctx))
}
}
// remember,
// the router already checks for the correct type,
// we did pre-calculate everything
// and now we will pre-calculate the method caller itself as well.
if p.ParamType == paramTypeInt {
return func(ctx context.Context, f interface{}) {
paramValue, _ := ctx.Params().GetInt(paramName)
f.(func(int))(paramValue)
}
}
if p.ParamType == paramTypeLong {
return func(ctx context.Context, f interface{}) {
paramValue, _ := ctx.Params().GetInt64(paramName)
f.(func(int64))(paramValue)
}
}
if p.ParamType == paramTypeBoolean {
return func(ctx context.Context, f interface{}) {
paramValue, _ := ctx.Params().GetBool(paramName)
f.(func(bool))(paramValue)
}
}
// else it's string or path, both of them are simple strings.
return func(ctx context.Context, f interface{}) {
paramValue := ctx.Params().Get(paramName)
f.(func(string))(paramValue)
// if it's static without any receivers then just call it.
return func(ctx context.Context, f reflect.Value) {
f.Interface().(func())()
}
}