bind

package
v0.9.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 23, 2025 License: BSD-3-Clause Imports: 10 Imported by: 1

Documentation

Overview

Copyright 2025 The Joe-cli Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. Package bind provides functions for creating late-bound actions and evaluators. It's common to produce actions or evaluators that delegate to other actions or evaluators, to values in the context, or to models where the values that are needed have been set. This package provides idioms that can simplify this code and encourage the pattern of separating the concerns.

For example, compare the equivalent flags:

&cli.App{
    Name: "a",
    Flags: []*cli.Flag{
        {
            Name: "cumbersome",
            Action: func(c *cli.Context) error {
                value := c.Int("")
                return logic(value)
            },
            Value: new(int),
        },
        {
            Name: "clean",
            Uses: bind.Call(logic, bind.Int()),
        },
    },
}

With the clean flag, you benefit from the implicit declaration of the type of the flag's Value and not having to map the value manually. In addition, it encourages you to factor out the logic as its own function with the signature func(int)error, which is decoupled from Joe's types and probably easier to test.

Evaluators

Say that you have an expression that has an operand "-name TEXT", and you have a function SetName(string)cli.Evaluator that can produce the evaluator that is actually used. You can use the following to simplify the binding of the string argument.

&cli.Arg {
    Name: "expression",
    Value: cli.Expression{
        Exprs: []*cli.Expr{
            {
                Name: "name",
                Args: cli.Args(cli.String()),
                Evaluator: bind.Evaluator(SetName, bind.String()),
            }
        }
    }
}

Notice that the bind.String() call doesn't require you to name the argument from which to obtain the value. When unspecified, it uses the first argument in the argument list for the Expr.

Copyright 2025 The Joe-cli Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Action

func Action[T any](fn func(T) cli.Action, t Binder[T]) cli.Action

Action obtains an action invokes the function to derive another action whilst binding the parameters. If this is added to the Uses timing, it will actually be run in the Action timing and the binders can also provide initializers if they have the method Initializer() Action (as the binders in this package do).

func Action2

func Action2[T, U any](fn func(T, U) cli.Action, t Binder[T], u Binder[U]) cli.Action

Action2 obtains an action invokes the function to derive another action whilst binding the parameters. If this is added to the Uses timing, it will actually be run in the Action timing and the binders can also provide initializers if they have the method Initializer() Action (as the binders in this package do).

func Action3

func Action3[T, U, V any](fn func(T, U, V) cli.Action, t Binder[T], u Binder[U], v Binder[V]) cli.Action

Action3 obtains an action invokes the function to derive another action whilst binding the parameters. If this is added to the Uses timing, it will actually be run in the Action timing and the binders can also provide initializers if they have the method Initializer() Action (as the binders in this package do).

func Call

func Call[T any](call func(T) error, t Binder[T]) cli.Action

Call obtains an action invokes the function, binding the parameters. If this is added to the Uses timing, it will actually be run in the Action timing and the binders can also provide initializers if they have the method Initializer() Action (as the binders in this package do).

func Call2

func Call2[T, U any](call func(T, U) error, t Binder[T], u Binder[U]) cli.Action

Call2 obtains an action invokes the function, binding the parameters. If this is added to the Uses timing, it will actually be run in the Action timing and the binders can also provide initializers if they have the method Initializer() Action (as the binders in this package do).

func Call3

func Call3[T, U, V any](call func(T, U, V) error, t Binder[T], u Binder[U], v Binder[V]) cli.Action

Call3 obtains an action invokes the function, binding the parameters. If this is added to the Uses timing, it will actually be run in the Action timing and the binders can also provide initializers if they have the method Initializer() Action (as the binders in this package do).

func Evaluator

func Evaluator[T any](factory func(T) expr.Evaluator, t Binder[T]) expr.Evaluator

Evaluator produces an evaluator from the bound values.

func Evaluator2

func Evaluator2[T, U any](eval func(T, U) expr.Evaluator, t Binder[T], u Binder[U]) expr.Evaluator

Evaluator2 produces an evaluator from the bound values.

func Evaluator3

func Evaluator3[T, U, V any](eval func(T, U, V) expr.Evaluator, t Binder[T], u Binder[U], v Binder[V]) expr.Evaluator

Evaluator3 produces an evaluator from the bound values.

func Indirect

func Indirect[T, V any](name any, call func(T, V) error, valopt ...V) cli.Action

Indirect binds a value to the specified option indirectly. For example, it is common to define a FileSet arg and a Boolean flag that controls whether or not the file set is enumerated recursively. You can use Indirect to update the arg indirectly by naming it and the bind function:

&cli.Arg{
    Name: "files",
    Value: new(cli.FileSet),
}
&cli.Flag{
    Name: "recursive",
    HelpText: "Whether files is recursively searched",
    Action: bind.Indirect("files", (*cli.FileSet).SetRecursive),
}

The name parameter specifies the name of the flag or arg that is affected. The bind function is the function to set the value, and valopt is optional, and if specified, indicates the value to set; otherwise, the value is read from the flag.

func Redirect

func Redirect[V any](name any, valopt ...V) cli.Action

Redirect binds a value to the specified option. A common use case for this action is to manually create aliases for other flags. For example, say you have a flag --proto= and a flag --tls1.2. You could use Redirect to support it.

&cli.Flag{
    Name: "proto",
}
&cli.Flag{
    Name: "tls1.2",
    HelpText: "Use TLS 1.2 connections",
    Action: bind.Redirect("proto", "tls1.2"),
}
&cli.Flag{
    Name: "tls1.3",
    HelpText: "Use TLS 1.3 connections",
    Action: bind.Redirect("proto", "tls1.3"),
}

The name parameter specifies the name of the flag or arg that is affected. The valopt is optional, and if specified, indicates the value to set; otherwise, the value is read from the flag.

func SetPointer added in v0.9.3

func SetPointer[V any](v *V, binder Binder[V]) cli.Action

SetPointer sets a pointer as the binding action

Types

type Binder

type Binder[T any] interface {
	// Bind obtains the value from the context
	Bind(context.Context) (T, error)
}

Binder provides a strategy for obtaining a value from the context

func BigFloat

func BigFloat(nameopt ...any) Binder[*big.Float]

BigFloat obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func BigInt

func BigInt(nameopt ...any) Binder[*big.Int]

BigInt obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Bool

func Bool(nameopt ...any) Binder[bool]

Bool obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Bytes

func Bytes(nameopt ...any) Binder[[]byte]

Bytes obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Context

func Context() Binder[*cli.Context]

Context binds the context as a parameter.

func ContextValue

func ContextValue[T any](key any) Binder[T]

ContextValue locates a value within the context.

func Duration

func Duration(nameopt ...any) Binder[time.Duration]

Duration obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Exact

func Exact[T any](valopt ...T) Binder[T]

Exact takes either the exact value that is specified or will take the value from the flag or arg.

func FileSet

func FileSet(nameopt ...any) Binder[*cli.FileSet]

FileSet obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Float32

func Float32(nameopt ...any) Binder[float32]

Float32 obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Float64

func Float64(nameopt ...any) Binder[float64]

Float64 obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func For

func For[T any](nameopt ...any) Binder[T]

For provides the binder of the specified type

func FromContext

func FromContext[T any](fn func(context.Context) T) Binder[T]

FromContext locates a value within the context. A common value for the argument is cli.FromContext to obtain the cli.Context pointer. Indeed, the function Context provides this behavior.

func IP

func IP(nameopt ...any) Binder[net.IP]

IP obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Int

func Int(nameopt ...any) Binder[int]

Int obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Int8

func Int8(nameopt ...any) Binder[int8]

Int8 obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Int16

func Int16(nameopt ...any) Binder[int16]

Int16 obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Int32

func Int32(nameopt ...any) Binder[int32]

Int32 obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Int64

func Int64(nameopt ...any) Binder[int64]

Int64 obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Interface

func Interface(nameopt ...any) Binder[any]

Interface obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func List

func List(nameopt ...any) Binder[[]string]

List obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Map

func Map(nameopt ...any) Binder[map[string]string]

Map obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func NameValue

func NameValue(nameopt ...any) Binder[*cli.NameValue]

NameValue obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func NameValues

func NameValues(nameopt ...any) Binder[[]*cli.NameValue]

NameValues obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Regexp

func Regexp(nameopt ...any) Binder[*regexp.Regexp]

Regexp obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func String

func String(nameopt ...any) Binder[string]

String obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func URL

func URL(nameopt ...any) Binder[*url.URL]

URL obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Uint

func Uint(nameopt ...any) Binder[uint]

Uint obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Uint8

func Uint8(nameopt ...any) Binder[uint8]

Uint8 obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Uint16

func Uint16(nameopt ...any) Binder[uint16]

Uint16 obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Uint32

func Uint32(nameopt ...any) Binder[uint32]

Uint32 obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Uint64

func Uint64(nameopt ...any) Binder[uint64]

Uint64 obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func Value

func Value[T any](nameopt ...any) Binder[T]

Value obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

type FileBinder

type FileBinder struct {
	// contains filtered or unexported fields
}

FileBinder provides a binder for [cli.File]

func File

func File(nameopt ...any) *FileBinder

File obtains a binder that obtains a value from the context. If the name is not specified, then either the current flag or arg is used or the corresponding argument by index. When present in the Uses pipeline, this also sets up the corresponding flag or arg with a reasonable default of the same type.

func (*FileBinder) Base

func (f *FileBinder) Base() Binder[string]

Base obtains the name for the file

func (*FileBinder) Bind

func (f *FileBinder) Bind(c context.Context) (*cli.File, error)

func (*FileBinder) Dir

func (f *FileBinder) Dir() Binder[string]

Dir obtains the name for the file

func (*FileBinder) Exists

func (f *FileBinder) Exists() Binder[bool]

Exists obtains the name for the file

func (*FileBinder) Ext

func (f *FileBinder) Ext() Binder[string]

Ext obtains the name for the file

func (*FileBinder) Name

func (f *FileBinder) Name() Binder[string]

Name obtains the name for the file

type Func

type Func[T any] func(c *cli.Context) (T, error)

Func provides a function that binds

func (Func[T]) Bind

func (f Func[T]) Bind(c context.Context) (T, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL