From a6eb86da71e0db1386f2b013eba31f12c53cc6b5 Mon Sep 17 00:00:00 2001 From: berik Date: Tue, 23 Aug 2022 15:02:19 +0200 Subject: [PATCH] Add recoverCatching recoverCatching tries to recover, exceptions in transformation cause an error result. --- build.gradle.kts | 5 ++++ .../com/github/michaelbull/result/Or.kt | 21 +++++++++++++ .../com/github/michaelbull/result/OrTest.kt | 30 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index c83c04f..86bc6d4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -195,6 +195,11 @@ subprojects { name.set("Dmitry Suzdalev") url.set("https://github.com/dimsuz") } + + contributor { + name.set("Berik Visschers") + url.set("https://visschers.nu/") + } } scm { diff --git a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Or.kt b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Or.kt index e61116b..b6d6ed7 100644 --- a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Or.kt +++ b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Or.kt @@ -66,6 +66,27 @@ public inline infix fun Result.recover(transform: (E) -> V): Ok } } +/** + * Returns the [transformation][transform] of the [error][Err.error], catching and encapsulating any + * thrown exception as a failure if this [Result] is [Err], otherwise this [Ok]. + */ +public inline infix fun Result.recoverCatching(transform: (E) -> V): Result { + contract { + callsInPlace(transform, InvocationKind.AT_MOST_ONCE) + } + + return when (this) { + is Ok -> this + is Err -> { + try { + Ok(transform(error)) + } catch (e: Throwable) { + Err(e) + } + } + } +} + /** * Returns the [transformation][transform] of the [error][Err.error] if this [Result] is [Err] * and satisfies the given [predicate], otherwise this [Result]. diff --git a/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/OrTest.kt b/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/OrTest.kt index 6abb300..bb20c46 100644 --- a/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/OrTest.kt +++ b/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/OrTest.kt @@ -82,6 +82,36 @@ class OrTest { } } + class RecoverCatching { + @Test + fun returnsValueIfOk() { + assertEquals( + expected = Ok(3000), + actual = Ok(3000).recoverCatching { 4000 } + ) + } + + @Test + fun returnsTransformedValueIfErr() { + assertEquals( + expected = Ok(2000), + actual = Err(4000).recoverCatching { 2000 } + ) + } + + @Test + fun returnsErrorIfTransformerThrows() { + val exception = IllegalArgumentException("throw me") + + assertEquals( + expected = exception, + actual = Err(4000) + .recoverCatching { throw exception } + .getError() + ) + } + } + class RecoverIf { @Test fun returnsValueIfOk() {