events/handler.go

63 lines
1.2 KiB
Go

//go:build !tinygo
// +build !tinygo
package events
import (
"errors"
"reflect"
)
type receiptHandler struct {
receiverFunc reflect.Value
funcType reflect.Type
}
func newReceiptHandler(receiver interface{}) (receiptHandler, error) {
val := reflect.ValueOf(receiver)
if val.Type().Kind() != reflect.Func {
return receiptHandler{}, errors.New("not a function")
}
return receiptHandler{receiverFunc: val, funcType: val.Type()}, nil
}
func (rh *receiptHandler) invoke(values preparedArgs) error {
args := make([]reflect.Value, rh.funcType.NumIn())
for i := range args {
args[i] = reflect.Zero(rh.funcType.In(i))
if i < len(values) {
if values[i].Type().AssignableTo(rh.funcType.In(i)) {
args[i] = values[i]
}
}
}
rets := rh.receiverFunc.Call(args)
if len(rets) == 0 {
return nil
}
lastRet := rets[len(rets)-1]
switch {
case lastRet.IsNil():
return nil
case lastRet.CanInterface():
err, ok := lastRet.Interface().(error)
if ok {
return err
}
}
return nil
}
type preparedArgs []reflect.Value
func prepareArgs(argIfacess []interface{}) preparedArgs {
values := make([]reflect.Value, len(argIfacess))
for i, a := range argIfacess {
values[i] = reflect.ValueOf(a)
}
return values
}