Add recoverCatching

recoverCatching tries to recover, exceptions in transformation cause an error result.
This commit is contained in:
berik 2022-08-23 15:02:19 +02:00 committed by Michael Bull
parent 44bb0c5314
commit a6eb86da71
3 changed files with 56 additions and 0 deletions

View File

@ -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 {

View File

@ -66,6 +66,27 @@ public inline infix fun <V, E> Result<V, E>.recover(transform: (E) -> V): Ok<V>
}
}
/**
* 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 <V, E> Result<V, E>.recoverCatching(transform: (E) -> V): Result<V, Throwable> {
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].

View File

@ -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() {