diff --git a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Map.kt b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Map.kt index 4016858..fdbfc2f 100644 --- a/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Map.kt +++ b/kotlin-result/src/commonMain/kotlin/com/github/michaelbull/result/Map.kt @@ -189,6 +189,23 @@ public inline fun Result.toErrorIf(predicate: (V) -> Boolean, trans } } +/** + * Returns the supplied [error] if this [Result] is [Ok] and the [value][Ok.value] is `null`, + * otherwise this [Result]. + * + * @see [toErrorIf] + */ +public inline fun Result.toErrorIfNull(error: () -> E): Result { + contract { + callsInPlace(error, InvocationKind.AT_MOST_ONCE) + } + + return toErrorIf( + { it == null }, + { error() } + ) +} + /** * Returns the [transformation][transform] of the [value][Ok.value] if this [Result] is [Ok] * and _does not_ satisfy the given [predicate], otherwise this [Result]. @@ -210,3 +227,20 @@ public inline fun Result.toErrorUnless(predicate: (V) -> Boolean, t is Err -> this } } + +/** + * Returns the supplied [error] unless this [Result] is [Ok] and the [value][Ok.value] is `null`, + * otherwise this [Result]. + * + * @see [toErrorUnless] + */ +public inline fun Result.toErrorUnlessNull(error: () -> E): Result { + contract { + callsInPlace(error, InvocationKind.AT_MOST_ONCE) + } + + return toErrorUnless( + { it == null }, + { error() } + ) +} diff --git a/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/MapTest.kt b/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/MapTest.kt index e4cdd6e..51c22a2 100644 --- a/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/MapTest.kt +++ b/kotlin-result/src/commonTest/kotlin/com/github/michaelbull/result/MapTest.kt @@ -2,6 +2,7 @@ package com.github.michaelbull.result import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertNull import kotlin.test.assertSame class MapTest { @@ -174,4 +175,79 @@ class MapTest { ) } } + + class ToErrorIfNull { + + @Test + fun returnsValueIfOk() { + val result = Ok("a").toErrorIfNull { "b" } + + result as Ok + + assertEquals( + expected = "a", + actual = result.value + ) + } + + @Test + fun returnsTransformedErrorIfNull() { + val result = Ok(null).toErrorIfNull { "a" } + + result as Err + + assertEquals( + expected = "a", + actual = result.error + ) + } + + @Test + fun returnsErrorIfErr() { + val result = Err("a").toErrorIfNull { "b" } + + result as Err + + assertEquals( + expected = "a", + actual = result.error + ) + } + } + + class ToErrorUnlessNull { + + @Test + fun returnsTransformedErrorIfNotNull() { + val result = Ok("a").toErrorUnlessNull { "b" } + + result as Err + + assertEquals( + expected = "b", + actual = result.error + ) + } + + @Test + fun returnsValueIfNull() { + val result = Ok(null).toErrorUnlessNull { "a" } + + result as Ok + + assertNull(result.value) + } + + @Test + fun returnsErrorIfErr() { + val result = Err("a").toErrorUnlessNull { "b" } + + result as Err + + assertEquals( + expected = "a", + actual = result.error + ) + } + } }