Documentation
¶
Overview ¶
Package result provides functional programming patterns for error handling and flow control.
This package offers comprehensive branching-flow context patterns to enhance the existing Result[T] type with pattern matching, conditional execution, pipeline composition, and parallel execution capabilities.
Key types:
- Result[T]: Type-safe wrapper for values that may contain errors
- BranchFlow[T]: Complex conditional branching with fallback support
- FlowBuilder[T]: Sequential pipeline composition
- ParallelFlow[T]: Concurrent execution with result tracking
Example usage:
flow := NewBranchFlow[int]().
Branch(func() bool { return isAdmin }, func() Result[int] { return Ok(42) }).
Fallback(func() Result[int] { return Ok(1) })
result := flow.Execute()
Package result provides functional programming patterns for error handling and flow control.
FlowBuilder and Pipeline types enable building complex pipelines with sequential execution, branching, parallel execution, and comprehensive error handling.
Key types:
- FlowBuilder[T]: Builder for constructing executable pipelines
- Pipeline[T]: Composed pipeline ready for execution
- ParallelFlow[T]: Concurrent executor for parallel operations
Example usage:
pipeline := NewFlowBuilder[CleanResult]().
Step("scan", func(ctx context.Context) Result[CleanResult] { return Scan(ctx) }).
Step("validate", func(ctx context.Context, r CleanResult) Result[CleanResult] { return Validate(ctx, r) })
result := pipeline.Execute(ctx)
Index ¶
- Variables
- func Match[T, U any](r Result[T], ok func(T) U, err func(error) U) U
- func Partition[T any](results []Result[T]) (ok []T, errs []error)
- type Branch
- type BranchFlow
- func (bf *BranchFlow[T]) Branch(condition func() bool, execute func() Result[T]) *BranchFlow[T]
- func (bf *BranchFlow[T]) BranchWithContext(ctx context.Context, condition func(context.Context) bool, ...) *BranchFlow[T]
- func (bf *BranchFlow[T]) BranchWithValue(value T, condition func(T) bool, execute func(T) Result[T]) *BranchFlow[T]
- func (bf *BranchFlow[T]) Execute() Result[T]
- func (bf *BranchFlow[T]) Fallback(execute func() Result[T]) *BranchFlow[T]
- func (bf *BranchFlow[T]) FallbackValue(value T) *BranchFlow[T]
- func (bf *BranchFlow[T]) Finalize(fn func(Result[T]) Result[T]) *BranchFlow[T]
- type Case
- type EmptyPipelineError
- type FlowBuilder
- func (fb *FlowBuilder[T]) Build() *Pipeline[T]
- func (fb *FlowBuilder[T]) Execute(ctx context.Context) Result[T]
- func (fb *FlowBuilder[T]) Step(name string, fn func(context.Context) Result[T]) *FlowBuilder[T]
- func (fb *FlowBuilder[T]) StepWithRetry(name string, maxRetries int, fn func(context.Context) Result[T]) *FlowBuilder[T]
- func (fb *FlowBuilder[T]) Then(name string, fn func(context.Context, T) Result[T]) *FlowBuilder[T]
- type NoBranchMatchedError
- type NoPreviousStepError
- type ParallelFlow
- func (pf *ParallelFlow[T]) Add(name string, fn func(context.Context) Result[T]) *ParallelFlow[T]
- func (pf *ParallelFlow[T]) Execute(ctx context.Context) map[string]Result[T]
- func (pf *ParallelFlow[T]) Failed() map[string]error
- func (pf *ParallelFlow[T]) Results() map[string]Result[T]
- func (pf *ParallelFlow[T]) Successful() map[string]T
- type Pipeline
- type Result
- func AndThen[T, U any](r Result[T], fn func(T) Result[U]) Result[U]
- func Err[T any](err error) Result[T]
- func Fold[T, U any](results []Result[T], initial U, fn func(acc U, val T) U) Result[U]
- func FoldAll[T any](results []Result[T]) Result[[]T]
- func Map[T, U any](r Result[T], fn func(T) U) Result[U]
- func MockSuccess[T any](value T, message string) Result[T]
- func Ok[T any](value T) Result[T]
- func PartitionResults[T any](results []Result[T]) (ok, errs []Result[T])
- func Sequence[T any](results []Result[T]) Result[[]T]
- func SwitchFlow[T, U any](value T, cases []Case[T, U], defaultCase func() Result[U]) Result[U]
- func SwitchFlowWithResult[T, U any](result Result[T], cases []Case[T, U], defaultCase func() Result[U]) Result[U]
- func Traverse[T, U any](items []T, fn func(T) Result[U]) Result[[]U]
- func (r Result[T]) Error() error
- func (r Result[T]) Filter(predicate func(T) bool, errMsg string) Result[T]
- func (r Result[T]) FilterWithError(predicate func(T) bool, err error) Result[T]
- func (r Result[T]) IsErr() bool
- func (r Result[T]) IsOk() bool
- func (r Result[T]) OrElse(fallback Result[T]) Result[T]
- func (r Result[T]) SafeError() (error, bool)
- func (r Result[T]) SafeValue() (T, error)
- func (r Result[T]) Tap(fn func(T)) Result[T]
- func (r Result[T]) TapErr(fn func(error)) Result[T]
- func (r Result[T]) Unless(fn func(error)) Result[T]
- func (r Result[T]) Unwrap() (T, error)
- func (r Result[T]) UnwrapOr(default_ T) T
- func (r Result[T]) Validate(predicate func(T) bool, errorMsg string) Result[T]
- func (r Result[T]) ValidateWithError(predicate func(T) bool, err error) Result[T]
- func (r Result[T]) Value() T
- func (r Result[T]) When(fn func(T)) Result[T]
- type Step
Constants ¶
This section is empty.
Variables ¶
var ErrEmptyPipeline = &EmptyPipelineError{}
ErrEmptyPipeline is returned when executing an empty pipeline.
var ErrNoBranchMatched = &NoBranchMatchedError{}
ErrNoBranchMatched is returned when no branch condition was satisfied and no fallback was provided.
var ErrNoPreviousStep = &NoPreviousStepError{}
ErrNoPreviousStep is returned when a Then() is called on an empty FlowBuilder.
Functions ¶
Types ¶
type Branch ¶
type Branch[T any] struct { Condition func() bool // Condition that determines if this branch is taken Execute func() Result[T] // Function to execute if condition is true }
Branch represents a conditional branch in a BranchFlow.
type BranchFlow ¶
type BranchFlow[T any] struct { // contains filtered or unexported fields }
BranchFlow enables complex conditional branching flows with fallback support. It allows chaining multiple conditional branches that are evaluated in order, with an optional fallback for when no branch matches.
func NewBranchFlow ¶
func NewBranchFlow[T any]() *BranchFlow[T]
NewBranchFlow creates a new BranchFlow.
func (*BranchFlow[T]) Branch ¶
func (bf *BranchFlow[T]) Branch(condition func() bool, execute func() Result[T]) *BranchFlow[T]
Branch adds a conditional branch to the flow. The condition is evaluated first; if true, Execute is called and its result is returned.
func (*BranchFlow[T]) BranchWithContext ¶
func (bf *BranchFlow[T]) BranchWithContext( ctx context.Context, condition func(context.Context) bool, execute func(context.Context) Result[T], ) *BranchFlow[T]
BranchWithContext adds a conditional branch with access to context. Useful for async or cancellable operations.
func (*BranchFlow[T]) BranchWithValue ¶
func (bf *BranchFlow[T]) BranchWithValue( value T, condition func(T) bool, execute func(T) Result[T], ) *BranchFlow[T]
BranchWithValue adds a conditional branch that evaluates a predicate on a value. This is useful when you have a value and want to branch based on its properties.
func (*BranchFlow[T]) Execute ¶
func (bf *BranchFlow[T]) Execute() Result[T]
Execute evaluates branches in order and returns the first matching result. If no branch matches and a fallback is set, executes the fallback. If no fallback is set, returns an error indicating no branch matched.
func (*BranchFlow[T]) Fallback ¶
func (bf *BranchFlow[T]) Fallback(execute func() Result[T]) *BranchFlow[T]
Fallback sets the fallback function to execute when no branch condition is true.
func (*BranchFlow[T]) FallbackValue ¶
func (bf *BranchFlow[T]) FallbackValue(value T) *BranchFlow[T]
FallbackValue provides a default value when no branch matches.
func (*BranchFlow[T]) Finalize ¶
func (bf *BranchFlow[T]) Finalize(fn func(Result[T]) Result[T]) *BranchFlow[T]
Finalize adds a finalizer function that transforms the result before returning. This is useful for adding logging, metrics, or additional validation.
type EmptyPipelineError ¶
type EmptyPipelineError struct{}
EmptyPipelineError indicates that the pipeline has no steps.
func (*EmptyPipelineError) Error ¶
func (e *EmptyPipelineError) Error() string
type FlowBuilder ¶
type FlowBuilder[T any] struct { // contains filtered or unexported fields }
FlowBuilder enables building complex pipelines with branching, parallel execution, and error handling.
func NewFlowBuilder ¶
func NewFlowBuilder[T any]() *FlowBuilder[T]
NewFlowBuilder creates a new FlowBuilder for the specified result type.
func (*FlowBuilder[T]) Build ¶
func (fb *FlowBuilder[T]) Build() *Pipeline[T]
Build converts the FlowBuilder to an executable Pipeline.
func (*FlowBuilder[T]) Execute ¶
func (fb *FlowBuilder[T]) Execute(ctx context.Context) Result[T]
Execute runs the pipeline and returns the final result.
func (*FlowBuilder[T]) Step ¶
func (fb *FlowBuilder[T]) Step(name string, fn func(context.Context) Result[T]) *FlowBuilder[T]
Step adds a named step to the pipeline.
func (*FlowBuilder[T]) StepWithRetry ¶
func (fb *FlowBuilder[T]) StepWithRetry( name string, maxRetries int, fn func(context.Context) Result[T], ) *FlowBuilder[T]
StepWithRetry adds a step with automatic retry on failure.
func (*FlowBuilder[T]) Then ¶
func (fb *FlowBuilder[T]) Then( name string, fn func(context.Context, T) Result[T], ) *FlowBuilder[T]
Then chains a new step that receives the output of the previous step.
type NoBranchMatchedError ¶
type NoBranchMatchedError struct{}
NoBranchMatchedError indicates that no branch condition was satisfied and no fallback was provided.
func (*NoBranchMatchedError) Error ¶
func (e *NoBranchMatchedError) Error() string
type NoPreviousStepError ¶
type NoPreviousStepError struct{}
NoPreviousStepError indicates that Then() was called on an empty FlowBuilder.
func (*NoPreviousStepError) Error ¶
func (e *NoPreviousStepError) Error() string
type ParallelFlow ¶
type ParallelFlow[T any] struct { // contains filtered or unexported fields }
ParallelFlow is a concurrent executor.
func NewParallelFlow ¶
func NewParallelFlow[T any]() *ParallelFlow[T]
NewParallelFlow creates a new ParallelFlow for concurrent execution.
func (*ParallelFlow[T]) Add ¶
func (pf *ParallelFlow[T]) Add(name string, fn func(context.Context) Result[T]) *ParallelFlow[T]
Add adds a step to the parallel flow.
func (*ParallelFlow[T]) Execute ¶
func (pf *ParallelFlow[T]) Execute(ctx context.Context) map[string]Result[T]
Execute runs all steps concurrently and returns a map of results.
func (*ParallelFlow[T]) Failed ¶
func (pf *ParallelFlow[T]) Failed() map[string]error
Failed returns only the failed results.
func (*ParallelFlow[T]) Results ¶
func (pf *ParallelFlow[T]) Results() map[string]Result[T]
Results returns the results after execution.
func (*ParallelFlow[T]) Successful ¶
func (pf *ParallelFlow[T]) Successful() map[string]T
Successful returns only the successful results.
type Pipeline ¶
type Pipeline[T any] struct { // contains filtered or unexported fields }
Pipeline represents a composed pipeline that can be executed.
type Result ¶
type Result[T any] struct { // contains filtered or unexported fields }
Result is a type-safe way to return values or errors.
func AndThen ¶
AndThen chains operations that return Result, flattening the result. If the result is an error, it returns an error result without calling the function. This enables chaining operations that can fail (like FlatMap in functional programming).
func Fold ¶
Fold reduces a slice of Results into a single Result by applying fn cumulatively. The accumulator starts with initial value. If any result is an error, Fold returns that error immediately (short-circuit).
func FoldAll ¶
FoldAll reduces a slice of Results into a single Result by collecting all Ok values. If any result is an error, FoldAll returns that error immediately (short-circuit). Returns a slice of all values.
func MockSuccess ¶
MockSuccess creates a successful result with warning message.
func PartitionResults ¶
PartitionResults separates results into successful and failed Results.
func Sequence ¶
Sequence converts a slice of Results to a Result of slice. If all results are Ok, returns Ok with all values. If any result is an error, returns Err with the first error encountered.
func SwitchFlow ¶
SwitchFlow is a simpler alternative to BranchFlow for simple value-based switching. It takes a value and a slice of cases, plus a default.
func SwitchFlowWithResult ¶
func SwitchFlowWithResult[T, U any]( result Result[T], cases []Case[T, U], defaultCase func() Result[U], ) Result[U]
SwitchFlowWithResult is similar to SwitchFlow but the predicates operate on Result values.
func Traverse ¶
Traverse applies fn to each item in items and sequences the results. If all results are Ok, returns Ok with all transformed values. If any result is an error, returns Err with the first error encountered.
func (Result[T]) Filter ¶
Filter returns the result if predicate is true, otherwise returns an error. If the result already has an error, it passes through the error.
func (Result[T]) FilterWithError ¶
FilterWithError returns the result if predicate is true, otherwise returns the provided error. If the result already has an error, it passes through the error.
func (Result[T]) OrElse ¶
OrElse returns the current result if successful, otherwise returns the fallback result. Useful for providing fallback values when operations fail.
func (Result[T]) Tap ¶
Tap applies a side-effect function to the value if successful. Returns the original result unchanged, useful for logging or other side effects.
func (Result[T]) TapErr ¶
TapErr applies a side-effect function to the error if present. Returns the original result unchanged, useful for error logging.
func (Result[T]) Unless ¶
Unless executes the given function if the result is an error, otherwise does nothing. Returns the original result for chaining.
func (Result[T]) UnwrapOr ¶
func (r Result[T]) UnwrapOr(default_ T) T
UnwrapOr returns value or default if error.
func (Result[T]) Validate ¶
Validate checks if the value satisfies the predicate. If the predicate returns false, it returns an error with the given message. If the result already has an error, it passes through the error.
func (Result[T]) ValidateWithError ¶
ValidateWithError checks if the value satisfies the predicate. If the predicate returns false, it returns the provided error. If the result already has an error, it passes through the error.