rslt

package
v0.42.0 Latest Latest
Warning

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

Go to latest
Published: Mar 17, 2026 License: MIT Imports: 1 Imported by: 0

README

result

Typed results for operations that may fail.

Result[R] stores a value or an error. The zero value is Ok with the zero value of R — an uninitialized Result (e.g. a struct field never assigned) silently reports success. Always construct explicitly via Ok, Err, or Of.

// Wrap a (T, error) return pair
res := rslt.Of(strconv.Atoi(input))
port := res.Or(8080)

Pairs with FanOut for per-item error and panic handling in concurrent workloads, and with FanOutAll for all-or-nothing behavior:

// Per-item outcomes — collect what you need
results := slice.FanOut(ctx, 8, urls, fetchURL)
pages, errs := rslt.CollectOkAndErr(results)
// All-or-nothing — first error cancels remaining work
pages, err := slice.FanOutAll(ctx, 8, urls, fetchURL)

What It Looks Like

// Construct
ok := rslt.Ok(42)
fail := rslt.Err[int](errors.New("not found"))

// From (T, error) pair
res := rslt.Of(strconv.Atoi("42"))
// Comma-ok extraction
if v, ok := res.Get(); ok {
    fmt.Println(v)
}
// Default value
port := res.Or(8080)
// Cross-type transform (standalone — Go methods can't introduce type params)
name := rslt.Map(userResult, User.Name)
// Dispatch by state
msg := rslt.Fold(res,
    func(err error) string { return "failed: " + err.Error() },
    func(v int) string { return fmt.Sprintf("got %d", v) },
)
// Detect panics from FanOut — panics are recovered per item
results := slice.FanOut(ctx, 8, urls, fetchURL)
for _, res := range results {
    if err, ok := res.GetErr(); ok {
        var pe *rslt.PanicError
        if errors.As(err, &pe) {
            log.Printf("panic: %v\nstack:\n%s", pe.Value, pe.Stack)
        }
    }
}

PanicError

FanOut recovers panics per item and wraps them as *PanicError. This type carries the original panic value and a stack trace. Detect it with errors.As:

var pe *rslt.PanicError
if errors.As(err, &pe) {
    log.Printf("panic: %v\nstack:\n%s", pe.Value, pe.Stack)
}

If the panic value was an error, PanicError.Unwrap() returns it — enabling errors.Is chains through the original error.

Operations

Create: Ok, Err, Of (from (T, error) pair)

Extract: Get, Unpack (to (R, error) pair), Or, OrCall, GetErr, IsOk, IsErr, MustGet

Transform: Convert (same type), FlatMap (method + standalone), MapErr (transform error), Map (cross-type, standalone), Fold (standalone), Lift (wrap func(A)(R, error)func(A) Result[R])

Side effects: IfOk, IfErr

Collect: CollectAll (all values or first error by index), CollectOk (successes only), CollectErr (errors only), CollectOkAndErr (both in one pass)

See pkg.go.dev for complete API documentation, the main README for installation, and the showcase for real-world comparisons.

Documentation

Overview

Package rslt provides a Result type for operations that may fail.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CollectAll

func CollectAll[R any](results []Result[R]) ([]R, error)

CollectAll returns all values if every result is Ok, or the first error by index order otherwise. Note: for concurrent results from [FanOut], index order may differ from completion order.

func CollectErr

func CollectErr[R any](results []Result[R]) []error

CollectErr returns the errors from all Err results, preserving order.

func CollectOk

func CollectOk[R any](results []Result[R]) []R

CollectOk returns the values from all Ok results, preserving order.

func CollectOkAndErr

func CollectOkAndErr[R any](results []Result[R]) ([]R, []error)

CollectOkAndErr splits results into Ok values and Err errors in a single pass, preserving order.

func Fold

func Fold[R, T any](res Result[R], onErr func(error) T, onOk func(R) T) T

Fold applies onErr if res is Err, or onOk if res is Ok.

func Lift

func Lift[A, R any](fn func(A) (R, error)) func(A) Result[R]

Lift wraps a fallible function into one that returns Result.

Types

type PanicError

type PanicError struct {
	Value any
	Stack []byte
}

PanicError wraps a recovered panic value and its stack trace. It is stored as *PanicError in Err results. Callers detect it via errors.As(err, &pe) where pe is *PanicError.

func (*PanicError) Error

func (e *PanicError) Error() string

Error returns a string representation of the panic value.

func (*PanicError) Unwrap

func (e *PanicError) Unwrap() error

Unwrap returns the panic value if it is an error, or nil otherwise. This preserves error chains: errors.Is(resultErr, context.Canceled) works when fn panics with a wrapped context error.

type Result

type Result[R any] struct {
	// contains filtered or unexported fields
}

Result represents the outcome of an operation that may fail. It holds either a value (Ok) or an error (Err).

The zero value is Ok containing R's zero value. This means an uninitialized Result (e.g. a struct field never assigned) silently reports success. Always construct results explicitly via Ok, Err, or Of.

func Err

func Err[R any](e error) Result[R]

Err returns a Result containing error e. Panics if e is nil.

func FlatMap

func FlatMap[R, S any](res Result[R], fn func(R) Result[S]) Result[S]

FlatMap returns the result of applying fn to the value if Ok, or Err with same error if Err.

func Map

func Map[R, S any](res Result[R], fn func(R) S) Result[S]

Map returns the result of applying fn to the value if res is Ok, or an Err with the same error if res is Err.

func Of

func Of[R any](r R, err error) Result[R]

Of returns a Result from a (value, error) pair — the signature returned by most Go functions. If err is non-nil the result is Err; otherwise Ok.

func Ok

func Ok[R any](r R) Result[R]

Ok returns a Result containing value r.

func (Result[R]) Convert

func (r Result[R]) Convert(fn func(R) R) Result[R]

Convert returns the result of applying fn to the value if r is Ok, or r unchanged if r is Err. For cross-type mapping (R -> S), use the standalone Map function. Convert is the same-type method form; Go does not allow generic methods with extra type parameters, so cross-type mapping requires a standalone function.

func (Result[R]) FlatMap

func (r Result[R]) FlatMap(fn func(R) Result[R]) Result[R]

FlatMap returns the result of applying fn to the value if Ok, or r unchanged if Err.

func (Result[R]) Get

func (r Result[R]) Get() (_ R, _ bool)

Get returns the value and true if r is Ok, or the zero value and false if r is Err.

func (Result[R]) GetErr

func (r Result[R]) GetErr() (_ error, _ bool)

GetErr returns the error and true if r is Err, or nil and false if r is Ok.

func (Result[R]) IfErr

func (r Result[R]) IfErr(fn func(error))

IfErr calls fn with the error if r is Err.

func (Result[R]) IfOk

func (r Result[R]) IfOk(fn func(R))

IfOk calls fn with the value if r is Ok.

func (Result[R]) IsErr

func (r Result[R]) IsErr() bool

IsErr reports whether r is an Err result.

func (Result[R]) IsOk

func (r Result[R]) IsOk() bool

IsOk reports whether r is an Ok result.

func (Result[R]) MapErr

func (r Result[R]) MapErr(fn func(error) error) Result[R]

MapErr returns a Result with the error transformed by fn if r is Err, or r unchanged if r is Ok. Useful for wrapping or annotating errors without losing the Result context. Panics if fn returns nil (same as Err).

func (Result[R]) MustGet

func (r Result[R]) MustGet() R

MustGet returns the value if r is Ok, or panics with the error if r is Err. The panic value wraps the original error, preserving error chains for errors.Is and errors.As after recovery.

func (Result[R]) Or

func (r Result[R]) Or(defaultVal R) R

Or returns the value if r is Ok, or defaultVal if r is Err.

func (Result[R]) OrCall

func (r Result[R]) OrCall(fn func() R) R

OrCall returns the value if r is Ok, or the result of calling fn if r is Err.

func (Result[R]) Unpack

func (r Result[R]) Unpack() (R, error)

Unpack returns the value and error as a standard Go (R, error) pair. Inverse of Of: Of(r.Unpack()) == r for all well-constructed results.

Jump to

Keyboard shortcuts

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