binder API

binder

package

API reference for the binder package.

T
type

HandlerFunc

HandlerFunc is a function that handles binding a set of string arguments to a field.

pkg/binder/binder.go:8-8
type HandlerFunc func(args []string) error
S
struct

Binder

Binder handles mapping and execution of field bindings.

pkg/binder/binder.go:11-15
type Binder struct

Methods

Handlers
Method

Handlers returns the registered handlers.

Returns

map[string]HandlerFunc
func (*Binder) Handlers() map[string]HandlerFunc
{
	return b.handlers
}
AddBool
Method

AddBool registers a custom handler for a boolean field.

Parameters

key string
fn func(bool) error
func (*Binder) AddBool(key string, fn func(bool) error)
{
	b.handlers[key] = func(args []string) error {
		var val bool
		if len(args) > 0 {
			fmt.Sscanf(args[0], "%t", &val)
		} else {
			val = true
		}
		return fn(val)
	}
}
AddInt
Method

AddInt registers a custom handler for an integer field.

Parameters

key string
fn func(int64) error
func (*Binder) AddInt(key string, fn func(int64) error)
{
	b.handlers[key] = func(args []string) error {
		if len(args) == 0 {
			return fmt.Errorf("missing value for %s", key)
		}
		var val int64
		if _, err := fmt.Sscanf(args[0], "%d", &val); err != nil {
			return err
		}
		return fn(val)
	}
}
AddStrings
Method

AddStrings registers a custom handler for a string slice field.

Parameters

key string
fn func([]string) error
func (*Binder) AddStrings(key string, fn func([]string) error)
{
	b.handlers[key] = fn
}
Run
Method

Run executes the handler for the given key with the provided arguments.

Parameters

key string
args []string

Returns

error
func (*Binder) Run(key string, args []string) error
{
	b.hooks.runBefore(key, args)

	h, ok := b.handlers[key]
	if !ok {
		return fmt.Errorf("no handler for key: %s", key)
	}

	if err := h(args); err != nil {
		return err
	}

	b.hooks.runAfter(key, args)
	return nil
}
BeforeHook
Method

BeforeHook registers a function to be called before a specific key is handled.

Parameters

key string
func (*Binder) BeforeHook(key string, fn HookFunc)
{
	b.hooks.addBefore(key, fn)
}
AfterHook
Method

AfterHook registers a function to be called after a specific key is handled.

Parameters

key string
func (*Binder) AfterHook(key string, fn HookFunc)
{
	b.hooks.addAfter(key, fn)
}
AutoDiscover
Method

AutoDiscover reflects on the destination struct to register default handlers.

Returns

error
func (*Binder) AutoDiscover() error
{
	v := reflect.ValueOf(b.dst)
	if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
		return fmt.Errorf("binder: destination must be a pointer to a struct")
	}

	elem := v.Elem()
	typ := elem.Type()

	for i := 0; i < elem.NumField(); i++ {
		field := elem.Field(i)
		fieldType := typ.Field(i)

		tag := fieldType.Tag.Get("flag")
		if tag == "" {
			continue
		}

		params := ParseTag(tag)
		long := params["long"]
		if long == "" {
			long = strings.ToLower(fieldType.Name)
		}

		// Register default handler if not already registered
		if _, ok := b.handlers[long]; !ok {
			b.RegisterDefaultHandler(field, long)
		}
	}

	return nil
}

Parameters

name string
func (*Binder) RegisterDefaultHandler(field reflect.Value, name string)
{
	switch field.Kind() {
	case reflect.Bool:
		b.handlers[name] = func(args []string) error {
			if len(args) > 0 {
				var val bool
				fmt.Sscanf(args[0], "%t", &val)
				field.SetBool(val)
			} else {
				field.SetBool(true)
			}
			return nil
		}
	case reflect.String:
		b.handlers[name] = func(args []string) error {
			if len(args) > 0 {
				field.SetString(args[0])
			}
			return nil
		}
	case reflect.Int, reflect.Int64:
		b.handlers[name] = func(args []string) error {
			if len(args) > 0 {
				var val int64
				fmt.Sscanf(args[0], "%d", &val)
				field.SetInt(val)
			}
			return nil
		}
	}
}
AddDuration
Method

AddDuration registers a custom handler for a duration field.

Parameters

key string
fn func(time.Duration) error
func (*Binder) AddDuration(key string, fn func(time.Duration) error)
{
	b.handlers[key] = func(args []string) error {
		if len(args) == 0 {
			return fmt.Errorf("missing value for %s", key)
		}
		val, err := time.ParseDuration(args[0])
		if err != nil {
			return err
		}
		return fn(val)
	}
}
AddEnum
Method

AddEnum registers a handler that validates against a set of allowed values.

Parameters

key string
choices []string
fn func(string) error
func (*Binder) AddEnum(key string, choices []string, fn func(string) error)
{
	b.handlers[key] = func(args []string) error {
		if len(args) == 0 {
			return fmt.Errorf("missing value for %s", key)
		}
		val := args[0]
		found := slices.Contains(choices, val)
		if !found {
			return fmt.Errorf("invalid value %s for %s, allowed: %v", val, key, choices)
		}
		return fn(val)
	}
}

Fields

Name Type Description
dst any
handlers map[string]HandlerFunc
hooks *hooks
F
function

NewBinder

NewBinder creates a new binder for the destination object.

Parameters

dst
any

Returns

error
pkg/binder/binder.go:18-30
func NewBinder(dst any) (*Binder, error)

{
	b := &Binder{
		dst:      dst,
		handlers: make(map[string]HandlerFunc),
		hooks:    newHooks(),
	}

	if err := b.AutoDiscover(); err != nil {
		return nil, err
	}

	return b, nil
}
F
function

ParseTag

Parameters

tag
string

Returns

map[string]string
pkg/binder/discovery.go:75-91
func ParseTag(tag string) map[string]string

{
	params := make(map[string]string)
	parts := strings.Split(tag, ",")
	for _, part := range parts {
		kv := strings.Split(part, ":")
		if len(kv) == 2 {
			params[strings.TrimSpace(kv[0])] = strings.TrimSpace(kv[1])
		} else {
			// Support flags without keys as long names (e.g. `flag:"verbose"`)
			key := strings.TrimSpace(part)
			if !strings.Contains(tag, ":") {
				params["long"] = key
			}
		}
	}
	return params
}
T
type

HookFunc

HookFunc is a function called before or after a value is bound.

pkg/binder/hooks.go:4-4
type HookFunc func(key string, args []string)
S
struct

hooks

pkg/binder/hooks.go:6-9
type hooks struct

Methods

addBefore
Method

Parameters

key string
func (*hooks) addBefore(key string, fn HookFunc)
{
	h.before[key] = append(h.before[key], fn)
}
addAfter
Method

Parameters

key string
func (*hooks) addAfter(key string, fn HookFunc)
{
	h.after[key] = append(h.after[key], fn)
}
runBefore
Method

Parameters

key string
args []string
func (*hooks) runBefore(key string, args []string)
{
	for _, fn := range h.before[key] {
		fn(key, args)
	}
}
runAfter
Method

Parameters

key string
args []string
func (*hooks) runAfter(key string, args []string)
{
	for _, fn := range h.after[key] {
		fn(key, args)
	}
}

Fields

Name Type Description
before map[string][]HookFunc
after map[string][]HookFunc
F
function

newHooks

Returns

pkg/binder/hooks.go:11-16
func newHooks() *hooks

{
	return &hooks{
		before: make(map[string][]HookFunc),
		after:  make(map[string][]HookFunc),
	}
}