diff --git a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/ThrowIfUnless.kt b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/ThrowIfUnless.kt new file mode 100644 index 0000000..087e6ad --- /dev/null +++ b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/ThrowIfUnless.kt @@ -0,0 +1,27 @@ +package com.github.michaelbull.result + +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + +/** + * If the [Result] is [Err] and contains a [Throwable], throws the [error][Err.error] + * if the [predicate] returns true. + * + * @throws E if [predicate] returns true. + */ +public inline fun Result.throwIf( + predicate: (E) -> Boolean +): Result { + contract { callsInPlace(predicate, InvocationKind.AT_MOST_ONCE) } + return onFailure { e -> if (predicate(e)) throw e } +} + +/** + * If the [Result] is [Err] and contains a [Throwable], throws the [error][Err.error] + * only if the [predicate] returns false. + * + * @throws E if [predicate] returns false. + */ +public inline fun Result.throwUnless( + predicate: (E) -> Boolean +): Result = throwIf { e -> predicate(e).not() } diff --git a/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/ThrowTest.kt b/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/ThrowTest.kt new file mode 100644 index 0000000..04ac939 --- /dev/null +++ b/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/ThrowTest.kt @@ -0,0 +1,64 @@ +package com.github.michaelbull.result + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith + +class ThrowTest { + + class ThrowIfTest { + @Test + fun throwsIfPredicateReturnsTrue() { + val result: Result = Err(RuntimeException()) + + assertFailsWith { + result.throwIf { _ -> true } + } + } + + @Test + fun nothingThrownIfPredicateReturnsFalse() { + val result: Result = Err(NullPointerException()) + + result.throwIf { _ -> false } + } + + @Test + fun doesntAlterOkValue() { + val result: Result = Ok("ok") + + assertEquals( + expected = "ok", + actual = result.throwIf(predicate = { false }).unwrap() + ) + } + } + + class ThrowUnlessTest { + @Test + fun throwsIfPredicateReturnsFalse() { + val result: Result = Err(RuntimeException()) + + assertFailsWith { + result.throwUnless { _ -> false } + } + } + + @Test + fun nothingThrownIfPredicateReturnsTrue() { + val result: Result = Err(NullPointerException()) + + result.throwUnless { _ -> true } + } + + @Test + fun doesntAlterOkValue() { + val result: Result = Ok("ok") + + assertEquals( + expected = "ok", + actual = result.throwUnless(predicate = { false }).unwrap() + ) + } + } +}