Files
httprunner/plugin/shared/utils.go

51 lines
1.5 KiB
Go

package shared
import (
"fmt"
"reflect"
)
// CallFunc calls function with arguments
// it is used when calling go plugin or builtin functions
func CallFunc(fn reflect.Value, args ...interface{}) (interface{}, error) {
fnArgsNum := fn.Type().NumIn()
if fnArgsNum > 0 && fn.Type().In(fnArgsNum-1).Kind() == reflect.Slice {
// last argument is slice, do not check arguments number
// e.g. ...interface{}
// e.g. a, b string, c ...interface{}
} else if fnArgsNum != len(args) {
// function arguments not match
return nil, fmt.Errorf("function arguments number not match, expect %d, got %d", fnArgsNum, len(args))
}
// arguments do not have slice, and arguments number matched
argumentsValue := make([]reflect.Value, len(args))
for index, argument := range args {
if argument == nil {
argumentsValue[index] = reflect.Zero(fn.Type().In(index))
} else {
argumentsValue[index] = reflect.ValueOf(args[index])
}
}
resultValues := fn.Call(argumentsValue)
if resultValues == nil {
// no returns
return nil, nil
} else if len(resultValues) == 2 {
// return two arguments: interface{}, error
if resultValues[1].Interface() != nil {
return resultValues[0].Interface(), resultValues[1].Interface().(error)
} else {
return resultValues[0].Interface(), nil
}
} else if len(resultValues) == 1 {
// return one arguments: interface{}
return resultValues[0].Interface(), nil
} else {
// return more than 2 arguments, unexpected
err := fmt.Errorf("function should return at most 2 arguments")
return nil, err
}
}