Add Result#{throwIf,throwUnless}

Closes #64, #66
This commit is contained in:
Joseph Cooper 2021-10-26 15:54:28 +01:00 committed by Michael Bull
parent f236e2674b
commit 3b87373b23
2 changed files with 100 additions and 0 deletions

View File

@ -105,3 +105,45 @@ public inline fun <V, E> Result<V, E>.recoverUnless(predicate: (E) -> Boolean, t
} }
} }
} }
/**
* Throws the [error][Err.error] if this [Result] is an [Err]
* and satisfies the given [predicate], otherwise this [Result].
*
* @see [takeIf]
*/
public inline fun <V, E : Throwable> Result<V, E>.throwIf(predicate: (E) -> Boolean): Result<V, E> {
contract {
callsInPlace(predicate, InvocationKind.AT_MOST_ONCE)
}
return when (this) {
is Ok -> this
is Err -> if (predicate(error)) {
throw error
} else {
this
}
}
}
/**
* Throws the [error][Err.error] if this [Result] is an [Err]
* and _does not_ satisfy the given [predicate], otherwise this [Result].
*
* @see [takeUnless]
*/
public inline fun <V, E : Throwable> Result<V, E>.throwUnless(predicate: (E) -> Boolean): Result<V, E> {
contract {
callsInPlace(predicate, InvocationKind.AT_MOST_ONCE)
}
return when (this) {
is Ok -> this
is Err -> if (!predicate(error)) {
throw error
} else {
this
}
}
}

View File

@ -181,4 +181,62 @@ class OrTest {
) )
} }
} }
class ThrowIf {
@Test
fun returnsValueIfOk() {
assertEquals(
expected = Ok(200),
actual = Ok(200).throwIf { true }
)
}
@Test
fun returnsErrIfPredicateDoesNotMatch() {
val error = RuntimeException("throw if")
assertEquals(
expected = Err(error),
actual = Err(error).throwIf { false }
)
}
@Test
fun throwsErrIfPredicateMatches() {
val error = RuntimeException("throw if")
assertFailsWith<RuntimeException>(error.message) {
Err(error).throwIf { true }
}
}
}
class ThrowUnless {
@Test
fun returnsValueIfOk() {
assertEquals(
expected = Ok(500),
actual = Ok(500).throwUnless { false }
)
}
@Test
fun returnsErrIfPredicateMatches() {
val error = RuntimeException("example")
assertEquals(
expected = Err(error),
actual = Err(error).throwUnless { true }
)
}
@Test
fun throwsErrIfPredicateDoesNotMatch() {
val error = RuntimeException("throw unless")
assertFailsWith<RuntimeException>(error.message) {
Err(error).throwUnless { false }
}
}
}
} }