123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- package fn
- import (
- "fmt"
- "testing"
- )
- // Result represents a value that can either be a success (T) or an error.
- type Result[T any] struct {
- Either[T, error]
- }
- // Ok creates a new Result with a success value.
- func Ok[T any](val T) Result[T] {
- return Result[T]{Either: NewLeft[T, error](val)}
- }
- // Err creates a new Result with an error.
- func Err[T any](err error) Result[T] {
- return Result[T]{Either: NewRight[T, error](err)}
- }
- // Errf creates a new Result with a new formatted error string.
- func Errf[T any](errString string, args ...any) Result[T] {
- return Result[T]{
- Either: NewRight[T, error](fmt.Errorf(errString, args...)),
- }
- }
- // Unpack extracts the value or error from the Result.
- func (r Result[T]) Unpack() (T, error) {
- var zero T
- return r.left.UnwrapOr(zero), r.right.UnwrapOr(nil)
- }
- // IsOk returns true if the Result is a success value.
- func (r Result[T]) IsOk() bool {
- return r.IsLeft()
- }
- // IsErr returns true if the Result is an error.
- func (r Result[T]) IsErr() bool {
- return r.IsRight()
- }
- // Map applies a function to the success value if it exists.
- func (r Result[T]) Map(f func(T) T) Result[T] {
- if r.IsOk() {
- return Ok(f(r.left.some))
- }
- return r
- }
- // MapErr applies a function to the error value if it exists.
- func (r Result[T]) MapErr(f func(error) error) Result[T] {
- if r.IsErr() {
- return Err[T](f(r.right.some))
- }
- return r
- }
- // Option returns the success value as an Option.
- func (r Result[T]) Option() Option[T] {
- return r.left
- }
- // WhenResult executes the given function if the Result is a success.
- func (r Result[T]) WhenResult(f func(T)) {
- r.left.WhenSome(func(t T) {
- f(t)
- })
- }
- // WhenErr executes the given function if the Result is an error.
- func (r Result[T]) WhenErr(f func(error)) {
- r.right.WhenSome(func(e error) {
- f(e)
- })
- }
- // UnwrapOr returns the success value or a default value if it's an error.
- func (r Result[T]) UnwrapOr(defaultValue T) T {
- return r.left.UnwrapOr(defaultValue)
- }
- // UnwrapOrElse returns the success value or computes a value from a function
- // if it's an error.
- func (r Result[T]) UnwrapOrElse(f func() T) T {
- return r.left.UnwrapOrFunc(f)
- }
- // UnwrapOrFail returns the success value or fails the test if it's an error.
- func (r Result[T]) UnwrapOrFail(t *testing.T) T {
- t.Helper()
- return r.left.UnwrapOrFail(t)
- }
- // FlatMap applies a function that returns a Result to the success value if it
- // exists.
- func (r Result[T]) FlatMap(f func(T) Result[T]) Result[T] {
- if r.IsOk() {
- return f(r.left.some)
- }
- return r
- }
- // AndThen is an alias for FlatMap. This along with OrElse can be used to
- // Railway Oriented Programming (ROP) by chaining successive computational
- // operations from a single result type.
- func (r Result[T]) AndThen(f func(T) Result[T]) Result[T] {
- return r.FlatMap(f)
- }
- // OrElse returns the original Result if it is a success, otherwise it returns
- // the provided alternative Result. This along with AndThen can be used to
- // Railway Oriented Programming (ROP).
- func (r Result[T]) OrElse(f func() Result[T]) Result[T] {
- if r.IsOk() {
- return r
- }
- return f()
- }
- // FlatMap applies a function that returns a Result[B] to the success value if
- // it exists.
- func FlatMap[A, B any](r Result[A], f func(A) Result[B]) Result[B] {
- if r.IsOk() {
- return f(r.left.some)
- }
- return Err[B](r.right.some)
- }
- // AndThen is an alias for FlatMap. This along with OrElse can be used to
- // Railway Oriented Programming (ROP).
- func AndThen[A, B any](r Result[A], f func(A) Result[B]) Result[B] {
- return FlatMap(r, f)
- }
|