Skip to content

Commit

Permalink
Extract recover functions to separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbull committed Feb 6, 2024
1 parent 325cebc commit 54b53d3
Show file tree
Hide file tree
Showing 6 changed files with 415 additions and 403 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,64 +41,3 @@ 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
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,82 +51,6 @@ public fun <V, E : Throwable> Result<V, E>.orElseThrow(): Ok<V> {
}
}

/**
* Returns the [transformation][transform] of the [error][Err.error] if this [Result] is [Err],
* otherwise this [Ok].
*/
public inline infix fun <V, E> Result<V, E>.recover(transform: (E) -> V): Ok<V> {
contract {
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
}

return when (this) {
is Ok -> this
is Err -> Ok(transform(error))
}
}

/**
* Returns the [transformation][transform] of the [error][Err.error], catching and encapsulating any
* thrown exception as a failure if this [Result] is [Err], otherwise this [Ok].
*/
public inline infix fun <V, E> Result<V, E>.recoverCatching(transform: (E) -> V): Result<V, Throwable> {
contract {
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
}

return when (this) {
is Ok -> this
is Err -> {
try {
Ok(transform(error))
} catch (e: Throwable) {
Err(e)
}
}
}
}

/**
* 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>.recoverIf(predicate: (E) -> Boolean, transform: (E) -> V): 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)) {
Ok(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>.recoverUnless(predicate: (E) -> Boolean, transform: (E) -> V): 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)) {
Ok(transform(error))
} else {
this
}
}
}

/**
* Throws the [error][Err.error] if this [Result] is an [Err] and satisfies the given
* [predicate], otherwise returns this [Result].
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package com.github.michaelbull.result

import kotlin.contracts.InvocationKind
import kotlin.contracts.contract

/**
* Returns the [transformation][transform] of the [error][Err.error] if this [Result] is [Err],
* otherwise this [Ok].
*/
public inline infix fun <V, E> Result<V, E>.recover(transform: (E) -> V): Ok<V> {
contract {
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
}

return when (this) {
is Ok -> this
is Err -> Ok(transform(error))
}
}

/**
* Returns the [transformation][transform] of the [error][Err.error], catching and encapsulating any
* thrown exception as a failure if this [Result] is [Err], otherwise this [Ok].
*/
public inline infix fun <V, E> Result<V, E>.recoverCatching(transform: (E) -> V): Result<V, Throwable> {
contract {
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
}

return when (this) {
is Ok -> this
is Err -> {
try {
Ok(transform(error))
} catch (e: Throwable) {
Err(e)
}
}
}
}

/**
* 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>.recoverIf(predicate: (E) -> Boolean, transform: (E) -> V): 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)) {
Ok(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>.recoverUnless(predicate: (E) -> Boolean, transform: (E) -> V): 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)) {
Ok(transform(error))
} else {
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
}
}
}
Loading

0 comments on commit 54b53d3

Please sign in to comment.