feat: Embed() option and Context.Call()

The former allows arbitrary structs to be embedded in the root of the
CLI, with optional tags.

The latter allows an arbitrary function to be called using Kong's
binding functionality.
This commit is contained in:
Alec Thomas
2022-11-22 23:30:10 +11:00
parent d974d7270a
commit bf0cbf5d7c
7 changed files with 126 additions and 29 deletions
+8 -1
View File
@@ -110,7 +110,7 @@ func (c *Context) Bind(args ...interface{}) {
//
// This will typically have to be called like so:
//
// BindTo(impl, (*MyInterface)(nil))
// BindTo(impl, (*MyInterface)(nil))
func (c *Context) BindTo(impl, iface interface{}) {
c.bindings.addTo(impl, iface)
}
@@ -719,6 +719,13 @@ func (c *Context) parseFlag(flags []*Flag, match string) (err error) {
return findPotentialCandidates(match, candidates, "unknown flag %s", match)
}
// Call an arbitrary function filling arguments with bound values.
func (c *Context) Call(fn any, binds ...interface{}) (out []interface{}, err error) {
fv := reflect.ValueOf(fn)
bindings := c.Kong.bindings.clone().add(binds...).add(c).merge(c.bindings) //nolint:govet
return callAnyFunction(fv, bindings)
}
// RunNode calls the Run() method on an arbitrary node.
//
// This is useful in conjunction with Visit(), for dynamically running commands.