diff --git a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Get.kt b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Get.kt index af46c06..ecdb26b 100644 --- a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Get.kt +++ b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Get.kt @@ -121,6 +121,39 @@ public inline infix fun Result.getErrorOrElse(transform: (V) -> E): } } +/** + * Returns the [value][Ok.value] if this [Result] is [Ok], otherwise throws the + * [error][Err.error]. + * + * This is functionally equivalent to [`getOrElse { throw it }`][getOrElse]. + */ +public fun Result.getOrThrow(): V { + contract { + returns() implies (this@getOrThrow is Ok) + } + + return when (this) { + is Ok -> value + is Err -> throw error + } +} + +/** + * Returns the [value][Ok.value] if this [Result] is [Ok], otherwise throws the + * [transformation][transform] of the [error][Err.error] to a [Throwable]. + */ +public inline infix fun Result.getOrThrow(transform: (E) -> Throwable): V { + contract { + returns() implies (this@getOrThrow is Ok) + callsInPlace(transform, InvocationKind.AT_MOST_ONCE) + } + + return when (this) { + is Ok -> value + is Err -> throw transform(error) + } +} + /** * Merges this [Result][Result] to [U], returning the [value][Ok.value] if this [Result] is [Ok], otherwise the * [error][Err.error]. diff --git a/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/GetTest.kt b/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/GetTest.kt index 47e08c2..f187843 100644 --- a/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/GetTest.kt +++ b/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/GetTest.kt @@ -2,6 +2,7 @@ package com.github.michaelbull.result import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertFailsWith import kotlin.test.assertNull @Suppress("IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION") @@ -54,6 +55,44 @@ class GetTest { } } + class GetOrThrow { + @Test + fun returnsValueIfOk() { + assertEquals( + expected = "hello", + actual = Ok("hello").getOrThrow() + ) + } + + @Test + fun throwsErrorIfErr() { + assertFailsWith { + Err(CustomException()).getOrThrow() + } + } + + class CustomException : Throwable() + } + + class GetOrThrowWithTransform { + @Test + fun returnsValueIfOk() { + assertEquals( + expected = "hello", + actual = Ok("hello").getOrThrow { CustomException("Failed") } + ) + } + + @Test + fun throwsTransformedErrorIfErr() { + assertFailsWith { + Err("error").getOrThrow { error -> CustomException(error) } + } + } + + class CustomException(message: String) : Throwable(message) + } + class GetErrorOr { @Test fun returnsDefaultValueIfOk() {