Documentation
¶
Index ¶
- Variables
- func Async[T any](ctx context.Context, fn Thunk[T]) <-chan Result[T]
- func Empty[T any]() T
- func IsEmpty[T any](val T) bool
- func Must[T any](val T, err error) T
- func MustCast[T any](val any) T
- func MustHave[T any](val T, ok bool) T
- func MustPass(err error)
- func MustTrue(ok bool)
- func Step[T any](flow *workflow, work func() Result[T], rollback func(error)) T
- func Workflow() *workflow
- type Option
- func CastOption[U any, T any](opt Option[T]) Option[U]
- func MapOption[T, U any](opt Option[T], fn func(T) U) Option[U]
- func MayCast[T any](val any) Option[T]
- func MayHave[T any](val T, ok bool) Option[T]
- func MayLookUp[T any](m map[string]T, key string) Option[T]
- func MaybeEmpty[T any](val T) Option[T]
- func MaybeNilPtr[T any](val *T) Option[T]
- func None[T any]() Option[T]
- func Some[T any](val T) Option[T]
- func (o Option[T]) Chain(mapper func(value T) Option[T]) Option[T]
- func (o Option[T]) Equal(other Option[T]) bool
- func (o Option[T]) Get() (T, bool)
- func (o *Option[T]) GobDecode(data []byte) error
- func (o Option[T]) GobEncode() ([]byte, error)
- func (o Option[T]) IsNone() bool
- func (o Option[T]) IsSome() bool
- func (o Option[T]) IsZero() bool
- func (o Option[T]) Map(fn func(value T) T) Option[T]
- func (o Option[T]) MarshalBinary() ([]byte, error)
- func (o Option[T]) MarshalJSON() ([]byte, error)
- func (o Option[T]) MarshalText() ([]byte, error)
- func (o Option[T]) Or(fallback T) T
- func (o Option[T]) OrElse(fn func() Option[T]) Option[T]
- func (o Option[T]) OrEmpty() T
- func (o *Option[T]) Scan(src any) error
- func (o Option[T]) Tap(fn func(value T)) Option[T]
- func (o Option[T]) TapNone(fn func()) Option[T]
- func (o Option[T]) ToAny() Option[any]
- func (o Option[T]) ToPointer() *T
- func (o Option[T]) ToResult() Result[T]
- func (o *Option[T]) UnmarshalBinary(data []byte) error
- func (o *Option[T]) UnmarshalJSON(b []byte) error
- func (o *Option[T]) UnmarshalText(data []byte) error
- func (o Option[T]) Value() (driver.Value, error)
- func (o Option[T]) Yield() T
- type Result
- func Await[T any](ctx context.Context, ch <-chan Result[T]) Result[T]
- func AwaitAll[T any](ctx context.Context, chans ...any) Result[[]T]
- func AwaitAllSettled[T any](ctx context.Context, chans ...any) []Result[T]
- func AwaitAllSettledT[T any](ctx context.Context, chans ...<-chan Result[T]) []Result[T]
- func AwaitAllT[T any](ctx context.Context, chans ...<-chan Result[T]) Result[[]T]
- func AwaitFirst[T any](ctx context.Context, chans ...any) Result[Tuple[T, int]]
- func AwaitFirstT[T any](ctx context.Context, chans ...<-chan Result[T]) Result[Tuple[T, int]]
- func AwaitZip[T1, T2 any](ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2]) Result[Tuple[T1, T2]]
- func AwaitZip3[T1, T2, T3 any](ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ...) Result[Tuple3[T1, T2, T3]]
- func AwaitZip4[T1, T2, T3, T4 any](ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ...) Result[Tuple4[T1, T2, T3, T4]]
- func AwaitZip5[T1, T2, T3, T4, T5 any](ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ...) Result[Tuple5[T1, T2, T3, T4, T5]]
- func AwaitZip6[T1, T2, T3, T4, T5, T6 any](ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ...) Result[Tuple6[T1, T2, T3, T4, T5, T6]]
- func AwaitZip7[T1, T2, T3, T4, T5, T6, T7 any](ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ...) Result[Tuple7[T1, T2, T3, T4, T5, T6, T7]]
- func AwaitZip8[T1, T2, T3, T4, T5, T6, T7, T8 any](ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ...) Result[Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
- func AwaitZip9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any](ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ...) Result[Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
- func CastResult[U, T any](res Result[T]) Result[U]
- func Do[T any](fn func() T) (result Result[T])
- func Err[T any](err error) Result[T]
- func MapResult[T, U any](res Result[T], fn func(T) U) Result[U]
- func Ok[T any](val T) Result[T]
- func Scoped[T, R any](acquire func() Result[T], use func(T) Result[R], release func(T)) Result[R]
- func Try[T any](val T, err error) Result[T]
- func TryCast[T any](val any) Result[T]
- func TryHave[T any](val T, ok bool) Result[T]
- func TryIf(ok bool) Result[Unit]
- func TryLookUp[T any](m map[string]T, key string) Result[T]
- func TryPass(err error) Result[Unit]
- func (r Result[T]) Catch(fn func(error) Result[T]) Result[T]
- func (r Result[T]) CatchIs(pred error, fallback T) Result[T]
- func (r Result[T]) CatchString(contains string, fallback T) Result[T]
- func (r Result[T]) Chain(fn func(T) Result[T]) Result[T]
- func (r Result[T]) Err() error
- func (r Result[T]) Get() (T, error)
- func (r Result[T]) IsErr() bool
- func (r Result[T]) IsOk() bool
- func (r Result[T]) Map(fn func(T) T) Result[T]
- func (r Result[T]) MapErr(fn func(error) error) Result[T]
- func (r Result[T]) MapErrIs(pred error, other error) Result[T]
- func (r Result[T]) MapErrorString(contains string, other error) Result[T]
- func (r Result[T]) Or(fallback T) T
- func (r Result[T]) OrEmpty() T
- func (r Result[T]) OrF(fallbackFn func(error) T) T
- func (r Result[T]) Tap(fn func(T)) Result[T]
- func (r Result[T]) TapErr(fn func(error)) Result[T]
- func (r Result[T]) ToAny() Result[any]
- func (r Result[T]) ToOption() Option[T]
- func (r Result[T]) ToPointer() *T
- func (r Result[T]) Yield() T
- type Suspendable
- type Suspendable0
- type Suspendable2
- type Suspendable3
- type Suspendable4
- type Suspendable5
- type Suspendable6
- type Suspendable7
- type Suspendable8
- type Suspendable9
- type Suspense
- type Suspense0
- type Suspense2
- type Suspense3
- type Suspense4
- type Suspense5
- type Suspense6
- type Suspense7
- type Suspense8
- type Suspense9
- type Thunk
- type Tuple
- type Tuple3
- type Tuple4
- type Tuple5
- type Tuple6
- type Tuple7
- type Tuple8
- type Tuple9
- type Unit
Constants ¶
This section is empty.
Variables ¶
var ErrAny = errors.New("[opera] any error sentinel")
ErrAny is a sentinel error value used to match any error.
var ErrAsyncAllOpsFailed = errors.New("all async operations failed")
var ErrAsyncArgumentNotChannelOfResult = errors.New("argument is not a channel of Result")
var ErrAsyncAwaitedValueCastError = errors.New("awaited value cast error")
var ErrAsyncChannelClosed = errors.New("channel closed")
var ErrInputCastFailed = errors.New("cast input failed")
var ErrNoSuchElement = errors.New("no such element")
var ErrPredicateFalse = errors.New("predicate returns false")
var ErrResultCastFailed = errors.New("inner value type cast failed")
Functions ¶
func Empty ¶
func Empty[T any]() T
Empty is a helper function that returns the zero value of type T.
func IsEmpty ¶
IsEmpty checks if the given value is the zero value of its type. It first tries to handle common types explicitly for performance, then falls back to using reflection.
func MustCast ¶
MustCast extracts the value from a successful Result of a type cast, bails out if there is an error.
func Step ¶
Step executes a workflow step with rollback support along with an workflow instance. If the step returns an error, all registered rollbacks are executed in reverse order. Caveat: `opera.Step` yield value of `Result` directly like `opera.Must`, . Example:
opera.Do(func() {
flow := opera.Workflow()
result1 := opera.Step(flow, step1, rollback1)
result2 := opera.Step(flow, step2, rollback2)
...
})
func Workflow ¶
func Workflow() *workflow
Workflow creates a new workflow instance. Rollbacks are registered per step and executed in reverse order if any step fails. Example:
opera.Do(func() {
flow := opera.Workflow()
result1 := opera.Step(flow, step1, rollback1)
result2 := opera.Step(flow, step2, rollback2)
...
})
Types ¶
type Option ¶
type Option[T any] struct { // contains filtered or unexported fields }
Option is a container for an optional value of type T. If value exists, Option is of type Some. If the value is absent, Option is of type None.
func CastOption ¶
CastOption tries to convert Option[T] to Option[U] and returns None if conversion fails.
func MapOption ¶ added in v0.2.0
MapOption applies a function to the value inside an Option[T] if it is Some, returning an Option[U].
func MayCast ¶
MayCast tries to cast val to type T and returns Some if successful, or None otherwise.
func MayLookUp ¶ added in v0.1.2
MayLookUp attempts to retrieve a value from a map by key, returning an Option.
func MaybeEmpty ¶
MaybeEmpty builds a Some Option when val is not empty, or None.
func MaybeNilPtr ¶
MaybeNilPtr builds a Some Option when val is not nil, or None.
func (Option[T]) Chain ¶
Chain executes the mapper function if value is present or returns None if absent.
func (Option[T]) Map ¶
Map executes the mapper function if value is present or returns None if absent.
func (Option[T]) MarshalBinary ¶
MarshalBinary is the interface implemented by an object that can marshal itself into a binary form.
func (Option[T]) MarshalJSON ¶
MarshalJSON encodes Option into json. Go 1.20+ relies on the IsZero method when the `omitempty` tag is used unless a custom MarshalJSON method is defined. Then the IsZero method is ignored. current best workaround is to instead use `omitzero` tag with Go 1.24+
func (Option[T]) MarshalText ¶
MarshalText implements the encoding.TextMarshaler interface.
func (Option[T]) Or ¶
func (o Option[T]) Or(fallback T) T
Or returns value if present or default value.
func (Option[T]) OrElse ¶
OrElse executes the function if value is absent or returns the original Option if present.
func (Option[T]) OrEmpty ¶
func (o Option[T]) OrEmpty() T
OrEmpty returns value if present or empty value.
func (Option[T]) Tap ¶
Tap executes the function if value is present and returns the original Option.
func (Option[T]) TapNone ¶
TapNone executes the function if value is absent and returns the original Option.
func (Option[T]) ToPointer ¶
func (o Option[T]) ToPointer() *T
ToPointer returns value if present or a nil pointer.
func (*Option[T]) UnmarshalBinary ¶
UnmarshalBinary is the interface implemented by an object that can unmarshal a binary representation of itself.
func (*Option[T]) UnmarshalJSON ¶
UnmarshalJSON decodes Option from json.
func (*Option[T]) UnmarshalText ¶
UnmarshalText implements the encoding.TextUnmarshaler interface.
type Result ¶
type Result[T any] struct { // contains filtered or unexported fields }
Result represents a value that may either be a success (Ok) or a failure (Err).
func Await ¶
Await blocks receiving a Result[T] or context cancellation. If the channel is nil, it returns Ok result with empty T value immediately.
func AwaitAll ¶
AwaitAll waits for all channels and returns collected values or first error. The order of returned values corresponds to the order of input channels. If a channel is nil, the corresponding value will be an empty T. Use AwaitAllSettled to collect all results including errors.
func AwaitAllSettled ¶
AwaitAllSettled awaits all channels and returns their results as a slice. The order of returned results corresponds to the order of input channels. If a channel is nil, the corresponding result will be an Ok with empty T. Use AwaitAll to return early on first error.
func AwaitAllSettledT ¶
AwaitAllSettledT is a type-safe wrapper for AwaitAllSettled for homogeneous channels.
func AwaitFirst ¶
AwaitFirst waits for the first successful Result from the provided channels errors are ignored unless all operations are failed. There may be [randomness](https://go.dev/tour/concurrency/5) if multiple channels are ready simultaneously.
func AwaitFirstT ¶
AwaitFirstT is a type-safe wrapper for AwaitFirst for homogeneous channels.
func AwaitZip ¶
func AwaitZip[T1, T2 any]( ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ) Result[Tuple[T1, T2]]
AwaitZip awaits 2 channels and returns their results as a tuple.
func AwaitZip3 ¶
func AwaitZip3[T1, T2, T3 any]( ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ch3 <-chan Result[T3], ) Result[Tuple3[T1, T2, T3]]
AwaitZip3 awaits 3 channels and returns their results as a tuple.
func AwaitZip4 ¶
func AwaitZip4[T1, T2, T3, T4 any]( ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ch3 <-chan Result[T3], ch4 <-chan Result[T4], ) Result[Tuple4[T1, T2, T3, T4]]
AwaitZip4 awaits 4 channels and returns their results as a tuple.
func AwaitZip5 ¶
func AwaitZip5[T1, T2, T3, T4, T5 any]( ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ch3 <-chan Result[T3], ch4 <-chan Result[T4], ch5 <-chan Result[T5], ) Result[Tuple5[T1, T2, T3, T4, T5]]
AwaitZip5 awaits 5 channels and returns their results as a tuple.
func AwaitZip6 ¶
func AwaitZip6[T1, T2, T3, T4, T5, T6 any]( ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ch3 <-chan Result[T3], ch4 <-chan Result[T4], ch5 <-chan Result[T5], ch6 <-chan Result[T6], ) Result[Tuple6[T1, T2, T3, T4, T5, T6]]
AwaitZip6 awaits 6 channels and returns their results as a tuple.
func AwaitZip7 ¶
func AwaitZip7[T1, T2, T3, T4, T5, T6, T7 any]( ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ch3 <-chan Result[T3], ch4 <-chan Result[T4], ch5 <-chan Result[T5], ch6 <-chan Result[T6], ch7 <-chan Result[T7], ) Result[Tuple7[T1, T2, T3, T4, T5, T6, T7]]
AwaitZip7 awaits 7 channels and returns their results as a tuple.
func AwaitZip8 ¶
func AwaitZip8[T1, T2, T3, T4, T5, T6, T7, T8 any]( ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ch3 <-chan Result[T3], ch4 <-chan Result[T4], ch5 <-chan Result[T5], ch6 <-chan Result[T6], ch7 <-chan Result[T7], ch8 <-chan Result[T8], ) Result[Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]]
AwaitZip8 awaits 8 channels and returns their results as a tuple.
func AwaitZip9 ¶
func AwaitZip9[T1, T2, T3, T4, T5, T6, T7, T8, T9 any]( ctx context.Context, ch1 <-chan Result[T1], ch2 <-chan Result[T2], ch3 <-chan Result[T3], ch4 <-chan Result[T4], ch5 <-chan Result[T5], ch6 <-chan Result[T6], ch7 <-chan Result[T7], ch8 <-chan Result[T8], ch9 <-chan Result[T9], ) Result[Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]]
AwaitZip9 awaits 9 channels and returns their results as a tuple.
func CastResult ¶
CastResult attempts to convert the value inside a Result[T] to type U.
func Do ¶
Do executes a function within a monadic context, capturing any errors that occur. If the function executes successfully, its result is wrapped in a successful Result. If the function panics (indicating a failure), the panic is caught and converted into an error Result.
func MapResult ¶ added in v0.2.0
MapResult applies a function to the value inside a Result[T] if it is successful, returning a Result[U].
func Scoped ¶
func Scoped[T, R any]( acquire func() Result[T], use func(T) Result[R], release func(T), ) Result[R]
/ Scoped manages a resource within a monadic context, ensuring that the resource is properly released after use.
func TryLookUp ¶ added in v0.1.2
TryLookUp attempts to retrieve a value from a map by key, returning a Result.
func (Result[T]) Catch ¶
Catch applies a function that returns a Result to the error if the Result is Err, otherwise returns the Ok unchanged.
func (Result[T]) CatchIs ¶
CatchIs tests the error using errors.Is, and if it matches, recovers by applying a handler function to produce a value. opera.AnyError can be used to match any error.
func (Result[T]) CatchString ¶
CatchString tests if the error message contains a substring, and if it does, recovers by providing a fallback value.
func (Result[T]) Chain ¶
Chain applies a function that returns a Result to the value if the Result is Ok, otherwise returns the Err unchanged.
func (Result[T]) Map ¶
Map applies a function to the value if the Result is Ok, otherwise returns the Err unchanged.
func (Result[T]) MapErr ¶
MapErr applies a function to the error if the Result is Err, otherwise returns the Ok unchanged.
func (Result[T]) MapErrIs ¶
MapErrIs tests the error using errors.Is, and if it matches, replaces it with another error. opera.ErrAny can be used to match any error.
func (Result[T]) MapErrorString ¶
MapErrorString tests if the error message contains a substring, and if it does, replaces it with another error.
func (Result[T]) Or ¶
func (r Result[T]) Or(fallback T) T
Or returns the value if the Result is Ok, otherwise returns the fallback value.
func (Result[T]) OrEmpty ¶
func (r Result[T]) OrEmpty() T
OrEmpty returns the value if the Result is Ok, otherwise returns the zero value of T.
func (Result[T]) OrF ¶
OrF returns the value if the Result is Ok, otherwise calls the fallback function with the error and returns its result.
func (Result[T]) Tap ¶
Tap executes a function with the value if the Result is Ok, returning the original Result.
func (Result[T]) TapErr ¶
TapErr executes a function with the error if the Result is Err, returning the original Result.
func (Result[T]) ToOption ¶
ToOption converts the Result to an Option, returning None if there is an error.
type Suspendable3 ¶
type Suspendable4 ¶
type Suspendable5 ¶
type Suspendable6 ¶
type Suspendable7 ¶
type Suspendable8 ¶
type Suspendable9 ¶
type Suspense0 ¶
SuspenseN is a type alias to represent suspended `Thunk` with N-arity arguments. A `SuspenseN` yields a `Thunk` with the same parameters as the original function which can be executed by `opera.Async`.
Example:
ctx := context.Background()
normalOp := func(a int, b string) opera.Result[string] {
return opera.Ok(fmt.Sprintf("%d - %s", a, b))
}
suspendedOp := opera.Suspend2(normalOp) thunk := suspendedOp(10, "hello") ch := opera.Async(ctx, thunk) result := opera.Await(ch).Yield()
func Suspend0 ¶
func Suspend0[T any](fn Suspendable0[T]) Suspense0[T]
SuspendN creates a new function which delays the execution of Result-returning function represented by `SuspenseN`. A `SuspenseN` yields a `Thunk` with the same parameters as the original function which can be executed by `opera.Async`.
Example:
ctx := context.Background()
normalOp := func(a int, b string) opera.Result[string] {
return opera.Ok(fmt.Sprintf("%d - %s", a, b))
}
suspendedOp := opera.Suspend2(normalOp) thunk := suspendedOp(10, "hello") ch := opera.Async(ctx, thunk) result := opera.Await(ch).Yield()
type Suspense2 ¶
func Suspend2 ¶
func Suspend2[T, A1, A2 any](fn Suspendable2[T, A1, A2]) Suspense2[T, A1, A2]
type Suspense3 ¶
func Suspend3 ¶
func Suspend3[T, A1, A2, A3 any](fn Suspendable3[T, A1, A2, A3]) Suspense3[T, A1, A2, A3]
type Suspense4 ¶
func Suspend4 ¶
func Suspend4[T, A1, A2, A3, A4 any]( fn Suspendable4[T, A1, A2, A3, A4], ) Suspense4[T, A1, A2, A3, A4]
type Suspense5 ¶
func Suspend5 ¶
func Suspend5[T, A1, A2, A3, A4, A5 any]( fn Suspendable5[T, A1, A2, A3, A4, A5], ) Suspense5[T, A1, A2, A3, A4, A5]
type Suspense6 ¶
func Suspend6 ¶
func Suspend6[T, A1, A2, A3, A4, A5, A6 any]( fn Suspendable6[T, A1, A2, A3, A4, A5, A6], ) Suspense6[T, A1, A2, A3, A4, A5, A6]
type Suspense7 ¶
func Suspend7 ¶
func Suspend7[T, A1, A2, A3, A4, A5, A6, A7 any]( fn Suspendable7[T, A1, A2, A3, A4, A5, A6, A7], ) Suspense7[T, A1, A2, A3, A4, A5, A6, A7]
type Suspense8 ¶
type Suspense8[T, A1, A2, A3, A4, A5, A6, A7, A8 any] = func(A1, A2, A3, A4, A5, A6, A7, A8) Thunk[T]
func Suspend8 ¶
func Suspend8[T, A1, A2, A3, A4, A5, A6, A7, A8 any]( fn Suspendable8[T, A1, A2, A3, A4, A5, A6, A7, A8], ) Suspense8[T, A1, A2, A3, A4, A5, A6, A7, A8]
type Suspense9 ¶
type Suspense9[T, A1, A2, A3, A4, A5, A6, A7, A8, A9 any] = func(A1, A2, A3, A4, A5, A6, A7, A8, A9) Thunk[T]
func Suspend9 ¶
func Suspend9[T, A1, A2, A3, A4, A5, A6, A7, A8, A9 any]( fn Suspendable9[T, A1, A2, A3, A4, A5, A6, A7, A8, A9], ) Suspense9[T, A1, A2, A3, A4, A5, A6, A7, A8, A9]
type Thunk ¶
Thunk is just a type alias for any function that defers computation until invoked with a context. A `Thunk` can yield `Result` with the help of `opera.Async`.
Example:
thunk := func(ctx context.Context) opera.Result[int] {
// perform some computation
return opera.Ok(42)
}
result := opera.Async(thunk).Yield()
type Tuple6 ¶
type Tuple6[T0, T1, T2, T3, T4, T5 any] = struct { V0 T0 V1 T1 V2 T2 V3 T3 V4 T4 V5 T5 }
type Tuple7 ¶
type Tuple7[T0, T1, T2, T3, T4, T5, T6 any] = struct { V0 T0 V1 T1 V2 T2 V3 T3 V4 T4 V5 T5 V6 T6 }
type Tuple8 ¶
type Tuple8[T0, T1, T2, T3, T4, T5, T6, T7 any] = struct { V0 T0 V1 T1 V2 T2 V3 T3 V4 T4 V5 T5 V6 T6 V7 T7 }