mirror of
https://github.com/kataras/iris.git
synced 2025-01-24 11:11:03 +01:00
82 lines
1.8 KiB
Go
82 lines
1.8 KiB
Go
|
package mvc2
|
||
|
|
||
|
import (
|
||
|
"reflect"
|
||
|
)
|
||
|
|
||
|
type serviceFieldBinder struct {
|
||
|
Index []int
|
||
|
Binder *InputBinder
|
||
|
}
|
||
|
|
||
|
func getServicesBinderForStruct(binders []*InputBinder, typ reflect.Type) func(elem reflect.Value) {
|
||
|
fields := lookupFields(typ, -1)
|
||
|
var validBinders []*serviceFieldBinder
|
||
|
|
||
|
for _, b := range binders {
|
||
|
for _, f := range fields {
|
||
|
if b.BinderType != serviceType {
|
||
|
continue
|
||
|
}
|
||
|
if equalTypes(b.BindType, f.Type) {
|
||
|
validBinders = append(validBinders,
|
||
|
&serviceFieldBinder{Index: f.Index, Binder: b})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if len(validBinders) == 0 {
|
||
|
return func(_ reflect.Value) {}
|
||
|
}
|
||
|
|
||
|
return func(elem reflect.Value) {
|
||
|
for _, b := range validBinders {
|
||
|
elem.FieldByIndex(b.Index).Set(b.Binder.BindFunc(nil))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// MustMakeServiceInputBinder calls the `MakeServiceInputBinder` and returns its first result, see its docs.
|
||
|
// It panics on error.
|
||
|
func MustMakeServiceInputBinder(service interface{}) *InputBinder {
|
||
|
s, err := MakeServiceInputBinder(service)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
return s
|
||
|
}
|
||
|
|
||
|
// MakeServiceInputBinder uses a difference/or strange approach,
|
||
|
// we make the services as bind functions
|
||
|
// in order to keep the rest of the code simpler, however we have
|
||
|
// a performance penalty when calling the function instead
|
||
|
// of just put the responsible service to the certain handler's input argument.
|
||
|
func MakeServiceInputBinder(service interface{}) (*InputBinder, error) {
|
||
|
if service == nil {
|
||
|
return nil, errNil
|
||
|
}
|
||
|
|
||
|
var (
|
||
|
val = reflect.ValueOf(service)
|
||
|
typ = val.Type()
|
||
|
)
|
||
|
|
||
|
if !goodVal(val) {
|
||
|
return nil, errBad
|
||
|
}
|
||
|
|
||
|
if indirectTyp(typ).Kind() != reflect.Struct {
|
||
|
// if the pointer's struct is not a struct then return err bad.
|
||
|
return nil, errBad
|
||
|
}
|
||
|
|
||
|
return &InputBinder{
|
||
|
BinderType: serviceType,
|
||
|
BindType: typ,
|
||
|
BindFunc: func(_ []reflect.Value) reflect.Value {
|
||
|
return val
|
||
|
},
|
||
|
}, nil
|
||
|
}
|