Add andThen{Recover,RecoverIf,RecoverUnless}
This commit is contained in:
parent
05a1e91298
commit
d4414b1a08
@ -41,3 +41,64 @@ public inline infix fun <V, E, U> Result<V, E>.andThen(transform: (V) -> Result<
|
||||
is Err -> this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the [transformation][transform] of the [error][Err.error] if this [Result] is [Err],
|
||||
* otherwise this [Result].
|
||||
*/
|
||||
public inline fun <V, E> Result<V, E>.andThenRecover(transform: (E) -> Result<V, E>): Result<V, E> {
|
||||
contract {
|
||||
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
is Ok -> this
|
||||
is Err -> transform(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the [transformation][transform] of the [error][Err.error] if this [Result] is [Err] and
|
||||
* satisfies the given [predicate], otherwise this [Result].
|
||||
*/
|
||||
public inline fun <V, E> Result<V, E>.andThenRecoverIf(
|
||||
predicate: (E) -> Boolean,
|
||||
transform: (E) -> Result<V, E>
|
||||
): Result<V, E> {
|
||||
contract {
|
||||
callsInPlace(predicate, InvocationKind.AT_MOST_ONCE)
|
||||
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
is Ok -> this
|
||||
is Err -> if (predicate(error)) {
|
||||
transform(error)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the [transformation][transform] of the [error][Err.error] if this [Result] is [Err]
|
||||
* and _does not_ satisfy the given [predicate], otherwise this [Result].
|
||||
*/
|
||||
public inline fun <V, E> Result<V, E>.andThenRecoverUnless(
|
||||
predicate: (E) -> Boolean,
|
||||
transform: (E) -> Result<V, E>
|
||||
): Result<V, E> {
|
||||
contract {
|
||||
callsInPlace(predicate, InvocationKind.AT_MOST_ONCE)
|
||||
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
is Ok -> this
|
||||
is Err -> if (!predicate(error)) {
|
||||
transform(error)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,4 +42,122 @@ class AndTest {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class AndThenRecover {
|
||||
@Test
|
||||
fun returnsValueIfOk() {
|
||||
assertEquals(
|
||||
expected = 5,
|
||||
actual = Ok(5).andThenRecover { Ok(7) }.get()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsTransformValueIfErr() {
|
||||
assertEquals(
|
||||
expected = 20,
|
||||
actual = Err(AndError).andThenRecover { Ok(20) }.get()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class AndThenRecoverIf {
|
||||
@Test
|
||||
fun returnsValueIfOk() {
|
||||
fun predicate(int: Int): Boolean {
|
||||
return int == 4000
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
expected = Ok(3000),
|
||||
actual = Ok(3000).andThenRecoverIf(::predicate) { Ok(2000) }
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsTransformedErrorAsOkIfErrAndPredicateMatch() {
|
||||
fun predicate(int: Int): Boolean {
|
||||
return int == 4000
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
expected = Ok(2000),
|
||||
actual = Err(4000).andThenRecoverIf(::predicate) { Ok(2000) }
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsTransformedErrorAsErrorIfErrAndPredicateMatch() {
|
||||
fun predicate(int: Int): Boolean {
|
||||
return int == 4000
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
expected = Err(2000),
|
||||
actual = Err(4000).andThenRecoverIf(::predicate) { Err(2000) }
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun doesNotReturnTransformationResultIfErrAndPredicateDoesNotMatch() {
|
||||
fun predicate(int: Int): Boolean {
|
||||
return int == 3000
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
expected = Err(4000),
|
||||
actual = Err(4000).andThenRecoverIf(::predicate) { Ok(2000) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class AndThenRecoverUnless {
|
||||
@Test
|
||||
fun returnsValueIfOk() {
|
||||
fun predicate(int: Int): Boolean {
|
||||
return int == 4000
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
expected = Ok(3000),
|
||||
actual = Ok(3000).andThenRecoverUnless(::predicate) { Ok(2000) }
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsTransformedErrorAsOkIfErrAndPredicateDoesNotMatch() {
|
||||
fun predicate(int: Int): Boolean {
|
||||
return int == 3000
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
expected = Ok(2000),
|
||||
actual = Err(4000).andThenRecoverUnless(::predicate) { Ok(2000) }
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsTransformedErrorAsErrorIfErrAndPredicateDoesNotMatch() {
|
||||
fun predicate(int: Int): Boolean {
|
||||
return int == 3000
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
expected = Err(2000),
|
||||
actual = Err(4000).andThenRecoverUnless(::predicate) { Err(2000) }
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun doesNotReturnTransformationResultIfErrAndPredicateMatches() {
|
||||
fun predicate(int: Int): Boolean {
|
||||
return int == 4000
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
expected = Err(4000),
|
||||
actual = Err(4000).andThenRecoverUnless(::predicate) { Ok(2000) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user