Restore SuccessOrFailure.kt to bootstrap (to be removed later)
This commit is contained in:
@@ -17,6 +17,8 @@ import kotlin.contracts.*
|
||||
import kotlin.internal.InlineOnly
|
||||
import kotlin.jvm.JvmField
|
||||
|
||||
// TODO: REMOVE AFTER BOOTSTRAP
|
||||
|
||||
/**
|
||||
* A discriminated union that encapsulates successful outcome with a value of type [T]
|
||||
* or a failure with an arbitrary [Throwable] exception.
|
||||
@@ -128,185 +130,3 @@ public inline class SuccessOrFailure<out T> @PublishedApi internal constructor(
|
||||
override fun toString(): String = "Failure($exception)"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the specified function [block] and returns its encapsulated result if invocation was successful,
|
||||
* catching and encapsulating any thrown exception as a failure.
|
||||
*/
|
||||
@InlineOnly public inline fun <R> runCatching(block: () -> R): SuccessOrFailure<R> {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return try {
|
||||
SuccessOrFailure.success(block())
|
||||
} catch (e: Throwable) {
|
||||
SuccessOrFailure.failure(e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the specified function [block] with `this` value as its receiver and returns its encapsulated result
|
||||
* if invocation was successful, catching and encapsulating any thrown exception as a failure.
|
||||
*/
|
||||
@InlineOnly public inline fun <T, R> T.runCatching(block: T.() -> R): SuccessOrFailure<R> {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return try {
|
||||
SuccessOrFailure.success(block())
|
||||
} catch (e: Throwable) {
|
||||
SuccessOrFailure.failure(e)
|
||||
}
|
||||
}
|
||||
|
||||
// -- extensions ---
|
||||
|
||||
/**
|
||||
* Returns the encapsulated value if this instance represents [success][SuccessOrFailure.isSuccess] or the
|
||||
* result of [onFailure] function for encapsulated exception if it is [failure][SuccessOrFailure.isFailure].
|
||||
*
|
||||
* Note, that an exception thrown by [onFailure] function is rethrown by this function.
|
||||
*
|
||||
* This function is shorthand for `fold(onSuccess = { it }, onFailure = onFailure)` (see [fold]).
|
||||
*/
|
||||
@InlineOnly public inline fun <R, T : R> SuccessOrFailure<T>.getOrElse(onFailure: (exception: Throwable) -> R): R {
|
||||
contract {
|
||||
callsInPlace(onFailure, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
return when(value) {
|
||||
is SuccessOrFailure.Failure -> onFailure(value.exception)
|
||||
else -> value as T
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encapsulated value if this instance represents [success][SuccessOrFailure.isSuccess] or the
|
||||
* [defaultValue] if it is [failure][SuccessOrFailure.isFailure].
|
||||
*
|
||||
* This function is shorthand for `getOrElse { defaultValue }` (see [getOrElse]).
|
||||
*/
|
||||
public fun <R, T : R> SuccessOrFailure<T>.getOrDefault(defaultValue: R): R =
|
||||
getOrElse { defaultValue }
|
||||
|
||||
/**
|
||||
* Returns the the result of [onSuccess] for encapsulated value if this instance represents [success][SuccessOrFailure.isSuccess]
|
||||
* or the result of [onFailure] function for encapsulated exception if it is [failure][SuccessOrFailure.isFailure].
|
||||
*
|
||||
* Note, that an exception thrown by [onSuccess] or by [onFailure] function is rethrown by this function.
|
||||
*/
|
||||
@InlineOnly public inline fun <R, T> SuccessOrFailure<T>.fold(
|
||||
onSuccess: (value: T) -> R,
|
||||
onFailure: (exception: Throwable) -> R
|
||||
): R {
|
||||
contract {
|
||||
callsInPlace(onSuccess, InvocationKind.AT_MOST_ONCE)
|
||||
callsInPlace(onFailure, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
return when(value) {
|
||||
is SuccessOrFailure.Failure -> onFailure(value.exception)
|
||||
else -> onSuccess(value as T)
|
||||
}
|
||||
}
|
||||
|
||||
// transformation
|
||||
|
||||
/**
|
||||
* Returns the encapsulated result of the given [transform] function applied to encapsulated value
|
||||
* if this instance represents [success][SuccessOrFailure.isSuccess] or the
|
||||
* original encapsulated exception if it is [failure][SuccessOrFailure.isFailure].
|
||||
*
|
||||
* Note, that an exception thrown by [transform] function is rethrown by this function.
|
||||
* See [mapCatching] for an alternative that encapsulates exceptions.
|
||||
*/
|
||||
@InlineOnly public inline fun <R, T> SuccessOrFailure<T>.map(transform: (value: T) -> R): SuccessOrFailure<R> {
|
||||
contract {
|
||||
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
return when(value) {
|
||||
is SuccessOrFailure.Failure -> SuccessOrFailure(value)
|
||||
else -> SuccessOrFailure.success(transform(value as T))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encapsulated result of the given [transform] function applied to encapsulated value
|
||||
* if this instance represents [success][SuccessOrFailure.isSuccess] or the
|
||||
* original encapsulated exception if it is [failure][SuccessOrFailure.isFailure].
|
||||
*
|
||||
* Any exception thrown by [transform] function is caught, encapsulated as a failure and returned by this function.
|
||||
* See [map] for an alternative that rethrows exceptions.
|
||||
*/
|
||||
@InlineOnly public inline fun <R, T> SuccessOrFailure<T>.mapCatching(transform: (value: T) -> R): SuccessOrFailure<R> {
|
||||
contract {
|
||||
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
return when(value) {
|
||||
is SuccessOrFailure.Failure -> SuccessOrFailure(value)
|
||||
else -> runCatching { transform(value as T) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encapsulated result of the given [transform] function applied to encapsulated exception
|
||||
* if this instance represents [failure][SuccessOrFailure.isFailure] or the
|
||||
* original encapsulated value if it is [success][SuccessOrFailure.isSuccess].
|
||||
*
|
||||
* Note, that an exception thrown by [transform] function is rethrown by this function.
|
||||
* See [recoverCatching] for an alternative that encapsulates exceptions.
|
||||
*/
|
||||
@InlineOnly public inline fun <R, T: R> SuccessOrFailure<T>.recover(transform: (exception: Throwable) -> R): SuccessOrFailure<R> {
|
||||
contract {
|
||||
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
return when(value) {
|
||||
is SuccessOrFailure.Failure -> SuccessOrFailure.success(transform(value.exception))
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encapsulated result of the given [transform] function applied to encapsulated exception
|
||||
* if this instance represents [failure][SuccessOrFailure.isFailure] or the
|
||||
* original encapsulated value if it is [success][SuccessOrFailure.isSuccess].
|
||||
*
|
||||
* Any exception thrown by [transform] function is caught, encapsulated as a failure and returned by this function.
|
||||
* See [recover] for an alternative that rethrows exceptions.
|
||||
*/
|
||||
@InlineOnly public inline fun <R, T: R> SuccessOrFailure<T>.recoverCatching(transform: (exception: Throwable) -> R): SuccessOrFailure<R> {
|
||||
contract {
|
||||
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
val value = value // workaround for inline classes BE bug
|
||||
return when(value) {
|
||||
is SuccessOrFailure.Failure -> runCatching { transform(value.exception) }
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
// "peek" onto value/exception and pipe
|
||||
|
||||
/**
|
||||
* Performs the given [action] on encapsulated value if this instance represents [success][SuccessOrFailure.isSuccess].
|
||||
* Returns the original `SuccessOrFailure` unchanged.
|
||||
*/
|
||||
@InlineOnly public inline fun <T> SuccessOrFailure<T>.onFailure(action: (exception: Throwable) -> Unit): SuccessOrFailure<T> {
|
||||
contract {
|
||||
callsInPlace(action, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
if (value is SuccessOrFailure.Failure) action(value.exception)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the given [action] on encapsulated exception if this instance represents [failure][SuccessOrFailure.isFailure].
|
||||
* Returns the original `SuccessOrFailure` unchanged.
|
||||
*/
|
||||
@InlineOnly public inline fun <T> SuccessOrFailure<T>.onSuccess(action: (value: T) -> Unit): SuccessOrFailure<T> {
|
||||
contract {
|
||||
callsInPlace(action, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
if (value !is SuccessOrFailure.Failure) action(value as T)
|
||||
return this
|
||||
}
|
||||
|
||||
// -------------------
|
||||
Reference in New Issue
Block a user