1
0
mirror of https://github.com/kataras/iris.git synced 2026-01-08 04:21:57 +00:00

add the ability to add custom parameter types to the interpreter and mapped macros with any number of macro functions - example added - although it's working it is not ready yet - I have to do some cleanup, doc comments and a TODO

Former-commit-id: 8ac751b649a3b8e59948fd4c89ad53d25f49d0d5
This commit is contained in:
Gerasimos (Makis) Maropoulos
2018-09-26 11:37:11 +03:00
parent 52a07df0f4
commit dc3c38b189
26 changed files with 1070 additions and 1036 deletions

View File

@@ -8,6 +8,17 @@ import (
func init() {
di.DefaultHijacker = func(fieldOrFuncInput reflect.Type) (*di.BindObject, bool) {
// if IsExpectingStore(fieldOrFuncInput) {
// return &di.BindObject{
// Type: memstoreTyp,
// BindType: di.Dynamic,
// ReturnValue: func(ctxValue []reflect.Value) reflect.Value {
// // return ctxValue[0].MethodByName("Params").Call(di.EmptyIn)[0]
// return ctxValue[0].MethodByName("Params").Call(di.EmptyIn)[0].Field(0) // the Params' memstore.Store.
// },
// }, true
// }
if !IsContext(fieldOrFuncInput) {
return nil, false
}

View File

@@ -132,9 +132,8 @@ func (s *FuncInjector) addValue(inputIndex int, value reflect.Value) bool {
}
if b.IsAssignable(inTyp) {
// println(inTyp.String() + " is assignable to " + val.Type().String())
// fmt.Printf("binded input index: %d for type: %s and value: %v with pointer: %v\n",
// i, b.Type.String(), value.String(), val.Pointer())
// i, b.Type.String(), inTyp.String(), inTyp.Pointer())
s.inputs = append(s.inputs, &targetFuncInput{
InputIndex: inputIndex,
Object: &b,
@@ -194,8 +193,8 @@ func (s *FuncInjector) Inject(in *[]reflect.Value, ctx ...reflect.Value) {
args := *in
for _, input := range s.inputs {
input.Object.Assign(ctx, func(v reflect.Value) {
// fmt.Printf("assign input index: %d for value: %v\n",
// input.InputIndex, v.String())
// fmt.Printf("assign input index: %d for value: %v of type: %s\n",
// input.InputIndex, v.String(), v.Type().Name())
args[input.InputIndex] = v
})

View File

@@ -101,6 +101,11 @@ func MakeReturnValue(fn reflect.Value, goodFunc TypeChecker) (func([]reflect.Val
if !v.IsValid() {
return zeroOutVal
}
// if v.String() == "<interface {} Value>" {
// println("di/object.go: " + v.String())
// // println("di/object.go: because it's interface{} it should be returned as: " + v.Elem().Type().String() + " and its value: " + v.Elem().Interface().(string))
// return v.Elem()
// }
return v
}

View File

@@ -54,6 +54,7 @@ func IsZero(v reflect.Value) bool {
// if can't interface, i.e return value from unexported field or method then return false
return false
}
zero := reflect.Zero(v.Type())
return v.Interface() == zero.Interface()
}
@@ -62,7 +63,10 @@ func IsZero(v reflect.Value) bool {
// If "v" is a nil pointer, Indirect returns a zero Value.
// If "v" is not a pointer, Indirect returns v.
func IndirectValue(v reflect.Value) reflect.Value {
return reflect.Indirect(v)
if k := v.Kind(); k == reflect.Ptr { //|| k == reflect.Interface {
return v.Elem()
}
return v
}
// ValueOf returns the reflect.Value of "o".
@@ -123,6 +127,11 @@ func equalTypes(got reflect.Type, expected reflect.Type) bool {
// fmt.Printf("expected interface = %s and got to set on the arg is: %s\n", expected.String(), got.String())
return got.Implements(expected)
}
// if got.String() == "interface {}" {
// return true
// }
return false
}
@@ -161,7 +170,6 @@ func lookupFields(elemTyp reflect.Type, skipUnexported bool, parentIndex []int)
for i, n := 0, elemTyp.NumField(); i < n; i++ {
f := elemTyp.Field(i)
if IndirectType(f.Type).Kind() == reflect.Struct &&
!structFieldIgnored(f) {
fields = append(fields, lookupFields(f.Type, skipUnexported, append(parentIndex, i))...)

View File

@@ -5,19 +5,31 @@ import (
"reflect"
"runtime"
"github.com/kataras/iris/context"
"github.com/kataras/iris/core/memstore"
"github.com/kataras/iris/hero/di"
"github.com/kataras/golog"
"github.com/kataras/iris/context"
)
var contextTyp = reflect.TypeOf((*context.Context)(nil)).Elem()
var (
contextTyp = reflect.TypeOf((*context.Context)(nil)).Elem()
memstoreTyp = reflect.TypeOf(memstore.Store{})
)
// IsContext returns true if the "inTyp" is a type of Context.
func IsContext(inTyp reflect.Type) bool {
return inTyp.Implements(contextTyp)
}
// IsExpectingStore returns true if the "inTyp" is a type of memstore.Store.
func IsExpectingStore(inTyp reflect.Type) bool {
print("di/handler.go: " + inTyp.String() + " vs " + memstoreTyp.String() + " : ")
println(inTyp == memstoreTyp)
return inTyp == memstoreTyp
}
// checks if "handler" is context.Handler: func(context.Context).
func isContextHandler(handler interface{}) (context.Handler, bool) {
h, is := handler.(context.Handler)
@@ -70,7 +82,7 @@ func makeHandler(handler interface{}, values ...reflect.Value) (context.Handler,
// is invalid when input len and values are not match
// or their types are not match, we will take look at the
// second statement, here we will re-try it
// using binders for path parameters: string, int, int64, bool.
// using binders for path parameters: string, int, int64, uint8, uint64, bool and so on.
// We don't have access to the path, so neither to the macros here,
// but in mvc. So we have to do it here.
if valid = funcInjector.Retry(new(params).resolve); !valid {

View File

@@ -19,64 +19,8 @@ type params struct {
func (p *params) resolve(index int, typ reflect.Type) (reflect.Value, bool) {
currentParamIndex := p.next
v, ok := resolveParam(currentParamIndex, typ)
v, ok := context.ParamResolverByKindAndIndex(typ.Kind(), currentParamIndex)
p.next = p.next + 1
return v, ok
}
func resolveParam(currentParamIndex int, typ reflect.Type) (reflect.Value, bool) {
var fn interface{}
switch typ.Kind() {
case reflect.Int:
fn = func(ctx context.Context) int {
// the second "ok/found" check is not necessary,
// because even if the entry didn't found on that "index"
// it will return an empty entry which will return the
// default value passed from the xDefault(def) because its `ValueRaw` is nil.
entry, _ := ctx.Params().GetEntryAt(currentParamIndex)
v, _ := entry.IntDefault(0)
return v
}
case reflect.Int64:
fn = func(ctx context.Context) int64 {
entry, _ := ctx.Params().GetEntryAt(currentParamIndex)
v, _ := entry.Int64Default(0)
return v
}
case reflect.Uint8:
fn = func(ctx context.Context) uint8 {
entry, _ := ctx.Params().GetEntryAt(currentParamIndex)
v, _ := entry.Uint8Default(0)
return v
}
case reflect.Uint64:
fn = func(ctx context.Context) uint64 {
entry, _ := ctx.Params().GetEntryAt(currentParamIndex)
v, _ := entry.Uint64Default(0)
return v
}
case reflect.Bool:
fn = func(ctx context.Context) bool {
entry, _ := ctx.Params().GetEntryAt(currentParamIndex)
v, _ := entry.BoolDefault(false)
return v
}
case reflect.String:
fn = func(ctx context.Context) string {
entry, _ := ctx.Params().GetEntryAt(currentParamIndex)
// print(entry.Key + " with index of: ")
// print(currentParamIndex)
// println(" and value: " + entry.String())
return entry.String()
}
default:
return reflect.Value{}, false
}
return reflect.ValueOf(fn), true
}