From 9bbd327a102fde4769e5d290ea419078b74a0e2e Mon Sep 17 00:00:00 2001 From: Keagan McClelland Date: Wed, 14 Aug 2024 15:22:30 -0700 Subject: [PATCH] fn: add Sink to Result --- fn/result.go | 10 ++++++++++ fn/result_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/fn/result.go b/fn/result.go index 3fa6492d9..6328a7891 100644 --- a/fn/result.go +++ b/fn/result.go @@ -224,6 +224,16 @@ func AndThen2[A, B, C any](ra Result[A], rb Result[B], }) } +// Sink consumes a Result, either propagating its error or processing its +// success value with a function that can fail. +func (r Result[A]) Sink(f func(A) error) error { + if r.IsErr() { + return r.right + } + + return f(r.left) +} + // TransposeResOpt transposes the Result[Option[A]] into a Option[Result[A]]. // This has the effect of leaving an A value alone while inverting the Result // and Option layers. If there is no internal A value, it will convert the diff --git a/fn/result_test.go b/fn/result_test.go index 5830b8214..2b5d942a4 100644 --- a/fn/result_test.go +++ b/fn/result_test.go @@ -70,3 +70,29 @@ func TestPropTransposeResOptInverts(t *testing.T) { require.NoError(t, quick.Check(f, nil)) } + +func TestSinkOnErrNoContinutationCall(t *testing.T) { + called := false + res := Err[uint8](errors.New("err")).Sink( + func(a uint8) error { + called = true + return nil + }, + ) + + require.False(t, called) + require.NotNil(t, res) +} + +func TestSinkOnOkContinuationCall(t *testing.T) { + called := false + res := Ok(uint8(1)).Sink( + func(a uint8) error { + called = true + return nil + }, + ) + + require.True(t, called) + require.Nil(t, res) +}