From 2d4c29e4102f7ce4087b2df1eb699d0d01dcb4b9 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Fri, 19 Apr 2024 12:07:26 +0200 Subject: [PATCH] feat(Result): introduce `Result::unwrapOr()` I'd like to introduce a function that allows to get inner value from Result if success and allows to bypass throwing an exception from Failure by providing a default value. --- src/Psl/Result/Failure.php | 5 +++++ src/Psl/Result/ResultInterface.php | 11 +++++++++++ src/Psl/Result/Success.php | 6 ++++++ tests/unit/Result/FailureTest.php | 8 ++++++++ tests/unit/Result/SuccessTest.php | 8 ++++++++ 5 files changed, 38 insertions(+) diff --git a/src/Psl/Result/Failure.php b/src/Psl/Result/Failure.php index 71db339b..8ca86254 100644 --- a/src/Psl/Result/Failure.php +++ b/src/Psl/Result/Failure.php @@ -44,6 +44,11 @@ public function getResult(): void throw $this->throwable; } + public function unwrapOr(mixed $default) + { + return $default; + } + /** * Since this is a failed result wrapper, this always returns the `Throwable` thrown during the operation. * diff --git a/src/Psl/Result/ResultInterface.php b/src/Psl/Result/ResultInterface.php index a37731cb..a69625d5 100644 --- a/src/Psl/Result/ResultInterface.php +++ b/src/Psl/Result/ResultInterface.php @@ -95,6 +95,17 @@ public function always(Closure $always): ResultInterface; */ public function getResult(); + /** + * Unwrap the Result if it is succeeded or return $default value. + * + * @param D $default + * + * @return T|D + * + * @template D + */ + public function unwrapOr(mixed $default); + /** * Return the underlying throwable, or fail with a invariant violation exception. * diff --git a/src/Psl/Result/Success.php b/src/Psl/Result/Success.php index 6b0e0ff7..b342de1f 100644 --- a/src/Psl/Result/Success.php +++ b/src/Psl/Result/Success.php @@ -44,6 +44,12 @@ public function getResult(): mixed return $this->value; } + public function unwrapOr(mixed $default) + { + return $this->value; + } + + /** * Since this is a successful result wrapper, this always throws a * `Psl\Exception\InvariantViolationException` saying that there was no exception thrown from the operation. diff --git a/tests/unit/Result/FailureTest.php b/tests/unit/Result/FailureTest.php index a37e5978..c8104a8f 100644 --- a/tests/unit/Result/FailureTest.php +++ b/tests/unit/Result/FailureTest.php @@ -33,6 +33,14 @@ public function testGetResult(): void $wrapper->getResult(); } + public function testUnwrapFailure(): void + { + $result = new Failure(new Exception()); + $value = $result->unwrapOr(null); + + static::assertNull($value); + } + public function testGetException(): void { $exception = new Exception('bar'); diff --git a/tests/unit/Result/SuccessTest.php b/tests/unit/Result/SuccessTest.php index af4f5bd0..b249817d 100644 --- a/tests/unit/Result/SuccessTest.php +++ b/tests/unit/Result/SuccessTest.php @@ -31,6 +31,14 @@ public function testGetResult(): void static::assertSame('hello', $wrapper->getResult()); } + public function testUnwrap(): void + { + $result = new Success('foo'); + $value = $result->unwrapOr(null); + + static::assertSame('foo', $value); + } + public function testGetException(): void { $wrapper = new Success('hello');