Adds Context.BindToProvider (#201)
This commit is contained in:
@@ -4,6 +4,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type bindings map[reflect.Type]func() (reflect.Value, error)
|
type bindings map[reflect.Type]func() (reflect.Value, error)
|
||||||
@@ -24,6 +26,30 @@ func (b bindings) add(values ...interface{}) bindings {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b bindings) addTo(impl, iface interface{}) {
|
||||||
|
valueOf := reflect.ValueOf(impl)
|
||||||
|
b[reflect.TypeOf(iface).Elem()] = func() (reflect.Value, error) { return valueOf, nil }
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b bindings) addProvider(provider interface{}) error {
|
||||||
|
pv := reflect.ValueOf(provider)
|
||||||
|
t := pv.Type()
|
||||||
|
if t.Kind() != reflect.Func || t.NumIn() != 0 || t.NumOut() != 2 || t.Out(1) != reflect.TypeOf((*error)(nil)).Elem() {
|
||||||
|
return errors.Errorf("%T must be a function with the signature func()(T, error)", provider)
|
||||||
|
}
|
||||||
|
rt := pv.Type().Out(0)
|
||||||
|
b[rt] = func() (reflect.Value, error) {
|
||||||
|
out := pv.Call(nil)
|
||||||
|
errv := out[1]
|
||||||
|
var err error
|
||||||
|
if !errv.IsNil() {
|
||||||
|
err = errv.Interface().(error) // nolint
|
||||||
|
}
|
||||||
|
return out[0], err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Clone and add values.
|
// Clone and add values.
|
||||||
func (b bindings) clone() bindings {
|
func (b bindings) clone() bindings {
|
||||||
out := make(bindings, len(b))
|
out := make(bindings, len(b))
|
||||||
|
|||||||
+9
-2
@@ -113,8 +113,15 @@ func (c *Context) Bind(args ...interface{}) {
|
|||||||
//
|
//
|
||||||
// BindTo(impl, (*MyInterface)(nil))
|
// BindTo(impl, (*MyInterface)(nil))
|
||||||
func (c *Context) BindTo(impl, iface interface{}) {
|
func (c *Context) BindTo(impl, iface interface{}) {
|
||||||
valueOf := reflect.ValueOf(impl)
|
c.bindings.addTo(impl, iface)
|
||||||
c.bindings[reflect.TypeOf(iface).Elem()] = func() (reflect.Value, error) { return valueOf, nil }
|
}
|
||||||
|
|
||||||
|
// BindToProvider allows binding of provider functions.
|
||||||
|
//
|
||||||
|
// This is useful when the Run() function of different commands require different values that may
|
||||||
|
// not all be initialisable from the main() function.
|
||||||
|
func (c *Context) BindToProvider(provider interface{}) error {
|
||||||
|
return c.bindings.addProvider(provider)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value returns the value for a particular path element.
|
// Value returns the value for a particular path element.
|
||||||
|
|||||||
+2
-18
@@ -180,8 +180,7 @@ func Bind(args ...interface{}) Option {
|
|||||||
// BindTo(impl, (*iface)(nil))
|
// BindTo(impl, (*iface)(nil))
|
||||||
func BindTo(impl, iface interface{}) Option {
|
func BindTo(impl, iface interface{}) Option {
|
||||||
return OptionFunc(func(k *Kong) error {
|
return OptionFunc(func(k *Kong) error {
|
||||||
valueOf := reflect.ValueOf(impl)
|
k.bindings.addTo(impl, iface)
|
||||||
k.bindings[reflect.TypeOf(iface).Elem()] = func() (reflect.Value, error) { return valueOf, nil }
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -192,22 +191,7 @@ func BindTo(impl, iface interface{}) Option {
|
|||||||
// not all be initialisable from the main() function.
|
// not all be initialisable from the main() function.
|
||||||
func BindToProvider(provider interface{}) Option {
|
func BindToProvider(provider interface{}) Option {
|
||||||
return OptionFunc(func(k *Kong) error {
|
return OptionFunc(func(k *Kong) error {
|
||||||
pv := reflect.ValueOf(provider)
|
return k.bindings.addProvider(provider)
|
||||||
t := pv.Type()
|
|
||||||
if t.Kind() != reflect.Func || t.NumIn() != 0 || t.NumOut() != 2 || t.Out(1) != reflect.TypeOf((*error)(nil)).Elem() {
|
|
||||||
return errors.Errorf("%T must be a function with the signature func()(T, error)", provider)
|
|
||||||
}
|
|
||||||
rt := pv.Type().Out(0)
|
|
||||||
k.bindings[rt] = func() (reflect.Value, error) {
|
|
||||||
out := pv.Call(nil)
|
|
||||||
errv := out[1]
|
|
||||||
var err error
|
|
||||||
if !errv.IsNil() {
|
|
||||||
err = errv.Interface().(error) // nolint
|
|
||||||
}
|
|
||||||
return out[0], err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user