refactor: reuse callAnyFunction for callFunction

Rather than duplicating basically identical calling logic
This commit is contained in:
Alec Thomas
2024-11-01 11:55:27 +11:00
parent 07c8821614
commit 373692af87
+6 -15
View File
@@ -78,28 +78,19 @@ func callFunction(f reflect.Value, bindings bindings) error {
if f.Kind() != reflect.Func { if f.Kind() != reflect.Func {
return fmt.Errorf("expected function, got %s", f.Type()) return fmt.Errorf("expected function, got %s", f.Type())
} }
in := []reflect.Value{}
t := f.Type() t := f.Type()
if t.NumOut() != 1 || !t.Out(0).Implements(callbackReturnSignature) { if t.NumOut() != 1 || !t.Out(0).Implements(callbackReturnSignature) {
return fmt.Errorf("return value of %s must implement \"error\"", t) return fmt.Errorf("return value of %s must implement \"error\"", t)
} }
for i := 0; i < t.NumIn(); i++ { out, err := callAnyFunction(f, bindings)
pt := t.In(i) if err != nil {
if argf, ok := bindings[pt]; ok { return err
argv, err := argf()
if err != nil {
return err
}
in = append(in, argv)
} else {
return fmt.Errorf("couldn't find binding of type %s for parameter %d of %s(), use kong.Bind(%s)", pt, i, t, pt)
}
} }
out := f.Call(in) ferr := out[0]
if out[0].IsNil() { if ferrv := reflect.ValueOf(ferr); !ferrv.IsValid() || ferrv.IsNil() {
return nil return nil
} }
return out[0].Interface().(error) //nolint return ferr.(error) //nolint:forcetypeassert
} }
func callAnyFunction(f reflect.Value, bindings bindings) (out []any, err error) { func callAnyFunction(f reflect.Value, bindings bindings) (out []any, err error) {