Documentation
¶
Overview ¶
Package configure provides utilities for applying functional options to objects.
Package configure provides a robust, type-safe, and flexible implementation of the Functional Options Pattern for Go. It is designed to simplify the initialization of complex objects by allowing optional parameters to be passed in a clean and readable way.
This pattern is ideal for constructors where many parameters are optional, have sensible defaults, or where you want to avoid a large number of arguments.
Usage ¶
The core of the pattern involves defining an `Option` type and functions that return these options.
## Basic Example: Configuring a Logger
Imagine you are creating a `Logger` that can be configured with different logging levels and output writers. The default is to log at the "info" level to standard output.
// 1. Define the object to be configured.
type Logger struct {
level string
out io.Writer
}
// 2. Create functions that return an `Option` for each configurable field.
func WithLevel(level string) configure.Option[Logger] {
return configure.OptionFunc[Logger](func(l *Logger) error {
l.level = level
return nil
})
}
func WithOutput(w io.Writer) configure.Option[Logger] {
return configure.OptionFunc[Logger](func(l *Logger) error {
l.out = w
return nil
})
}
// 3. Create a constructor that applies the options to a default instance.
func NewLogger(options ...configure.Option[Logger]) (*Logger, error) {
// Start with default values.
l := &Logger{
level: "info",
out: os.Stdout,
}
// Apply any provided options.
configure.ApplyWith(l, options...)
// You can also perform validation after applying options.
if l.level == "" {
return nil, fmt.Errorf("log level cannot be empty")
}
return l, nil
}
Now, you can create loggers with different configurations easily:
// A default logger (info level, stdout).
logger1, _ := NewLogger()
// A debug-level logger.
logger2, _ := NewLogger(WithLevel("debug"))
// A logger that writes to a file.
file, _ := os.Create("app.log")
logger3, _ := NewLogger(WithLevel("error"), WithOutput(file))
For more advanced usage, including stateful builders and compilation, refer to the function-specific documentation.
Index ¶
- func Apply[T any, O OptionFunc[T]](target *T, opts []O) *T
- func ApplyAny[T any](target *T, opts []any) (*T, error)
- func ApplyAnyWith[T any](target *T, opts ...any) (*T, error)
- func ApplyE[T any, O OptionFuncE[T]](target *T, opts []O) (*T, error)
- func ApplyWith[T any](target *T, opts ...Option[T]) *T
- func ApplyWithE[T any](target *T, opts ...OptionE[T]) (*T, error)
- func Chain[S any, T OptionFunc[S]](opts ...T) T
- func ChainE[S any, T OptionFuncE[S]](opts ...T) T
- func Compile[C any, P any](factory func(c *C) (*P, error), builder *Builder[C]) (*P, error)
- func IsConfigError(err error) bool
- func IsEmptyTargetValueError(err error) bool
- func IsExecutionFailedError(err error) bool
- func IsUnsupportedTypeError(err error) bool
- func New[T any, O OptionFunc[T]](opts []O) *T
- func NewAny[T any](opts ...any) (*T, error)
- func NewE[T any, O OptionFuncE[T]](opts []O) (*T, error)
- func NewWith[T any](opts ...Option[T]) *T
- func NewWithE[T any](opts ...OptionE[T]) (*T, error)
- type Applier
- type ApplierE
- type Builder
- type ConfigError
- type ErrorCode
- type Option
- type OptionE
- type OptionFunc
- type OptionFuncAny
- type OptionFuncE
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
func Apply[T any, O OptionFunc[T]](target *T, opts []O) *T
Apply applies a slice of options to the target object. It is the core, high-performance function for applying a homogeneous set of type-safe options. Its generic constraint allows for custom-defined option types, such as `type MyOption func(*T)`.
The `opts` parameter is a slice of options. If you have a variadic list of options (e.g., `WithFoo(), WithBar()`), use the `ApplyWith` convenience wrapper instead.
For handling mixed option types, see ApplyAny.
func ApplyAny ¶
ApplyAny applies a slice of options of various types (any) to the target object. This function provides flexibility by using reflection to handle heterogeneous options, at the cost of compile-time type safety and a minor performance overhead.
The `opts` parameter is a slice of options. If you have a variadic list of options (e.g., `WithFoo(), WithBar()`), use the `ApplyAnyWith` convenience wrapper instead.
For type-safe, high-performance application, see Apply or ApplyE.
func ApplyAnyWith ¶
ApplyAnyWith is the variadic convenience wrapper for ApplyAny.
func ApplyE ¶
func ApplyE[T any, O OptionFuncE[T]](target *T, opts []O) (*T, error)
ApplyE applies a slice of error-returning options to the target object. It is the core, high-performance function for applying a homogeneous set of type-safe, error-returning options. Its generic constraint allows for custom-defined option types.
The `opts` parameter is a slice of options. If you have a variadic list of options (e.g., `WithFoo(), WithBar()`), use the `ApplyWithE` convenience wrapper instead.
For handling mixed option types, see ApplyAny.
func ApplyWith ¶
ApplyWith is the variadic convenience wrapper for Apply. It is useful for applying a short, explicit list of options.
Example:
ApplyWith(config, WithTimeout(5*time.Second), WithPort(8080))
func ApplyWithE ¶
ApplyWithE is the variadic convenience wrapper for ApplyE. It is useful for applying a short, explicit list of options.
func Chain ¶ added in v0.9.0
func Chain[S any, T OptionFunc[S]](opts ...T) T
Chain combines multiple options (of any type satisfying OptionFunc[S]) into a single option. The returned option will apply all provided options in sequence.
func ChainE ¶ added in v0.9.0
func ChainE[S any, T OptionFuncE[S]](opts ...T) T
ChainE combines multiple error-returning options (of any type satisfying OptionFuncE[S]) into a single option. The returned option will apply all provided options in sequence. If any option returns an error, the chain stops and that error is returned.
func Compile ¶
Compile creates a final product `P` by first building a configuration `C` using the provided `builder`, and then passing the result to a `factory` function. This function acts as the primary top-level entry point for the Config -> Product workflow, emphasizing the factory's role in producing the final product from the configuration.
func IsConfigError ¶
IsConfigError checks if the given error is a *ConfigError.
func IsEmptyTargetValueError ¶
IsEmptyTargetValueError checks if the error is a ConfigError with the code ErrEmptyTargetValue.
func IsExecutionFailedError ¶
IsExecutionFailedError checks if the error is a ConfigError with the code ErrExecutionFailed.
func IsUnsupportedTypeError ¶
IsUnsupportedTypeError checks if the error is a ConfigError with the code ErrUnsupportedType.
func New ¶
func New[T any, O OptionFunc[T]](opts []O) *T
New creates a new instance of T and applies the given options. It is a convenient, type-safe constructor for creating objects with homogeneous options. For mixed-type or error-returning options, see NewAny or NewE.
func NewAny ¶ added in v0.5.0
NewAny creates a new instance of T, applies the given options of any type, and returns it. It is a convenient top-level constructor for simple object creation where the configuration type and the product type are the same.
It uses ApplyAny for maximum flexibility in accepting options.
func NewE ¶ added in v0.5.0
func NewE[T any, O OptionFuncE[T]](opts []O) (*T, error)
NewE creates a new instance of T, applies the error-returning options, and returns the configured instance or an error. It is a convenient, type-safe constructor for creating objects with homogeneous, error-returning options.
Types ¶
type Applier ¶
type Applier[T any] interface { Apply(*T) }
Applier is an interface for types that can apply a configuration to an object. It provides an extension point for ApplyAny, allowing custom types to be used as options without reflection.
type ApplierE ¶
ApplierE is an interface for types that can apply a configuration and return an error. It provides an extension point for ApplyAny, allowing custom types to be used as options without reflection.
type Builder ¶
type Builder[C any] struct { // contains filtered or unexported fields }
Builder provides a fluent interface for collecting and applying options. It is ideal for scenarios where configuration options are gathered progressively from different parts of an application.
The generic type C represents the configuration type being built, and is expected to be a struct type. Using a pointer type for C as the generic parameter (e.g., Builder[*MyConfig]) is not recommended as it can lead to unexpected behavior and double-pointers.
func NewBuilder ¶
NewBuilder creates a new configuration builder. It can optionally take a base configuration object. If provided, this base configuration will be cloned and used as the starting point for applying options when `Build` is called. If no base is provided, a zero-value instance of C will be used.
Panics if the generic type C is itself a pointer type (e.g., Builder[*MyConfig]), as this is an unsupported and likely unintended usage pattern that leads to double-pointers.
func (*Builder[C]) Add ¶
Add adds one or more options to the builder. It supports a fluent, chainable API.
func (*Builder[C]) AddWhen ¶
AddWhen conditionally adds an option to the builder based on a condition. If `condition` is true, `optIfTrue` is added. If `condition` is false and `optIfFalse` is provided (as the first element of the variadic parameter), then `optIfFalse` is added instead. It supports a fluent, chainable API.
type ConfigError ¶
type ConfigError struct {
// Code is the category of the error.
Code ErrorCode
// TypeString is the string representation of the option's type.
TypeString string
// Err is the underlying error, if any.
Err error
}
ConfigError is a custom error type for the configure package. It wraps an original error while providing additional context, such as the type of option that caused the failure and a specific error code.
func (*ConfigError) Error ¶
func (e *ConfigError) Error() string
Error implements the standard error interface.
func (*ConfigError) Unwrap ¶
func (e *ConfigError) Unwrap() error
Unwrap makes ConfigError compatible with the standard library's errors.Is and errors.As functions, allowing for proper error chain inspection.
type ErrorCode ¶
type ErrorCode int
ErrorCode defines the specific category of a configuration error.
const ( // ErrUnsupportedType indicates that an option's type is not supported by // the ApplyAny function. ErrUnsupportedType ErrorCode = iota // ErrExecutionFailed indicates that an option function returned an error // during its execution. ErrExecutionFailed // ErrEmptyTargetValue indicates that a nil pointer was passed as the target // for configuration. ErrEmptyTargetValue )
Error codes for specific configuration failures.
type Option ¶
type Option[T any] func(*T)
Option represents a function that configures an object of type T. It is the primary, non-error-returning type for the Functional Options Pattern.
type OptionE ¶
OptionE represents a function that configures an object of type T and may return an error. The 'E' suffix is a convention for "Error".
func OptionSetE
deprecated
OptionSetE bundles multiple error-returning options into a single option. If any option in the set returns an error, the application stops and the error is returned.
Deprecated: Use ChainE instead for more generic and flexible error-returning option chaining.
func WithValidation ¶
WithValidation creates an option that validates the target object. If the validator function returns an error, the configuration process will stop.
type OptionFunc ¶ added in v0.9.0
type OptionFunc[T any] interface { ~func(*T) }
OptionFunc is a generic constraint that permits any function type whose underlying type is func(*T). This enables the top-level Apply function to accept custom-defined option types, such as `type MyOption func(*T)`.
type OptionFuncAny ¶ added in v0.9.0
type OptionFuncAny[T any] interface { OptionFuncE[T] | OptionFunc[T] | any }
OptionFuncAny is a generic constraint that permits any function type whose underlying type is either func(*T) or func(*T) error. This provides a convenient way to create functions that can accept both error-returning and non-error-returning function options.
type OptionFuncE ¶ added in v0.9.0
OptionFuncE is a generic constraint that permits any function type whose underlying type is func(*T) error. This enables the top-level ApplyE function to accept custom-defined, error-returning option types.