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.internal.InlineOnly
|
||||||
import kotlin.jvm.JvmField
|
import kotlin.jvm.JvmField
|
||||||
|
|
||||||
|
// TODO: REMOVE AFTER BOOTSTRAP
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A discriminated union that encapsulates successful outcome with a value of type [T]
|
* A discriminated union that encapsulates successful outcome with a value of type [T]
|
||||||
* or a failure with an arbitrary [Throwable] exception.
|
* 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)"
|
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