From 5faad77f33b0a9df39c5775ca531b9564c9570bb Mon Sep 17 00:00:00 2001 From: Keagan McClelland Date: Tue, 6 Aug 2024 15:38:14 -0700 Subject: [PATCH] fn: add conversions between Result and Option --- fn/option.go | 19 +++++++++++++++++++ fn/option_test.go | 17 +++++++++++++++++ fn/result.go | 14 ++++++++++++++ fn/result_test.go | 8 ++++++++ 4 files changed, 58 insertions(+) diff --git a/fn/option.go b/fn/option.go index b1f2e237b..06007f781 100644 --- a/fn/option.go +++ b/fn/option.go @@ -1,6 +1,7 @@ package fn import ( + "fmt" "testing" "github.com/stretchr/testify/require" @@ -232,3 +233,21 @@ func OptionToRight[O, L, R any](o Option[O], l L) Either[L, O] { return NewLeft[L, O](l) } + +// SomeToOk allows you to convert an Option value to a Result with your own +// error. If the Option contained a Some, then the supplied error is ignored +// and Some is converted to Ok. +func (o Option[A]) SomeToOk(err error) Result[A] { + return Result[A]{ + OptionToLeft[A, A, error](o, err), + } +} + +// SomeToOkf allows you to convert an Option value to a Result with your own +// error message. If the Option contains a Some, then the supplied message is +// ignored and Some is converted to Ok. +func (o Option[A]) SomeToOkf(errString string, args ...interface{}) Result[A] { + return Result[A]{ + OptionToLeft[A, A, error](o, fmt.Errorf(errString, args...)), + } +} diff --git a/fn/option_test.go b/fn/option_test.go index 53a924827..484132d69 100644 --- a/fn/option_test.go +++ b/fn/option_test.go @@ -1,6 +1,8 @@ package fn import ( + "errors" + "fmt" "testing" "github.com/stretchr/testify/require" @@ -9,3 +11,18 @@ import ( func TestOptionUnwrapOrFail(t *testing.T) { require.Equal(t, Some(1).UnwrapOrFail(t), 1) } + +func TestSomeToOk(t *testing.T) { + err := errors.New("err") + require.Equal(t, Some(1).SomeToOk(err), Ok(1)) + require.Equal(t, None[uint8]().SomeToOk(err), Err[uint8](err)) +} + +func TestSomeToOkf(t *testing.T) { + errStr := "err" + require.Equal(t, Some(1).SomeToOkf(errStr), Ok(1)) + require.Equal( + t, None[uint8]().SomeToOkf(errStr), + Err[uint8](fmt.Errorf(errStr)), + ) +} diff --git a/fn/result.go b/fn/result.go index e94675e6e..c8de5aa6b 100644 --- a/fn/result.go +++ b/fn/result.go @@ -79,15 +79,29 @@ func (r Result[T]) MapErr(f func(error) error) Result[T] { } // Option returns the success value as an Option. +// +// Deprecated: Use OkToSome instead. func (r Result[T]) Option() Option[T] { return r.Either.LeftToOption() } +// OkToSome mutes the error value of the result. +func (r Result[T]) OkToSome() Option[T] { + return r.Either.LeftToOption() +} + // WhenResult executes the given function if the Result is a success. +// +// Deprecated: Use WhenOk instead. func (r Result[T]) WhenResult(f func(T)) { r.WhenLeft(f) } +// WhenOk executes the given function if the Result is a success. +func (r Result[T]) WhenOk(f func(T)) { + r.WhenLeft(f) +} + // WhenErr executes the given function if the Result is an error. func (r Result[T]) WhenErr(f func(error)) { r.WhenRight(f) diff --git a/fn/result_test.go b/fn/result_test.go index 38ebed84a..fd21e4443 100644 --- a/fn/result_test.go +++ b/fn/result_test.go @@ -1,6 +1,7 @@ package fn import ( + "errors" "testing" "github.com/stretchr/testify/require" @@ -9,3 +10,10 @@ import ( func TestResultUnwrapOrFail(t *testing.T) { require.Equal(t, Ok(1).UnwrapOrFail(t), 1) } + +func TestOkToSome(t *testing.T) { + require.Equal(t, Ok(1).OkToSome(), Some(1)) + require.Equal( + t, Err[uint8](errors.New("err")).OkToSome(), None[uint8](), + ) +}