Package-level declarations

Types

Link copied to clipboard
value class ApiResult<out T>

A class that represents a result of an operation.

Link copied to clipboard
open class ConditionNotSatisfiedException(message: String? = "ApiResult condition was not satisfied") : IllegalArgumentException

Exception representing unsatisfied condition when using errorIf

Link copied to clipboard
class NotFinishedException(message: String? = "ApiResult is still in the Loading state") : IllegalStateException

An exception that is thrown when an attempt to retrieve a result of an ApiResult is being made when the result is Loading

Properties

Link copied to clipboard

Create an ApiResult from this value, based on the type of it.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

ApiResult.Error.e's stack trace as string

Functions

Link copied to clipboard

Accumulates all errors from this collection and splits them into two lists:

Link copied to clipboard
infix inline fun <T, R> ApiResult<T>.apply(block: T.() -> R): ApiResult<R>

Alias for map that takes this as a parameter

Link copied to clipboard
inline fun <T> Flow<T>.asApiResult(): Flow<ApiResult<T>>

Emits Loading before this flow starts to be collected. Then maps all results to their values, then catches Exceptions and maps them to Errors

Link copied to clipboard
inline fun <T> Flow<T>.catchExceptions(crossinline action: suspend FlowCollector<T>.(Exception) -> Unit): Flow<T>

Catches Exceptions only and rethrows kotlin.Throwables (like kotlin.Errors).

Link copied to clipboard
infix inline fun <T> ApiResult<T>.chain(another: (T) -> ApiResult<*>): ApiResult<T>

Call another and retrieve the result. If the result is success, continue (the result of calling another is discarded). If the result is an error, propagate it to this. Effectively, requires for another ApiResult to succeed before proceeding with this one.

Link copied to clipboard
inline fun <T> ApiResult<T>.errorIf(exception: (T) -> Exception = { ConditionNotSatisfiedException() }, predicate: (T) -> Boolean): ApiResult<T>

Makes this an Error if predicate returns true

Link copied to clipboard
inline fun <T, R : Iterable<T>> ApiResult<R>.errorIfEmpty(exception: () -> Exception = { ConditionNotSatisfiedException("Collection was empty") }): ApiResult<R>
@JvmName(name = "sequenceErrorIfEmpty")
inline fun <T, R : Sequence<T>> ApiResult<R>.errorIfEmpty(exception: () -> Exception = { ConditionNotSatisfiedException("Sequence was empty") }): ApiResult<R>

Makes this an error if the collection is empty.

Link copied to clipboard
inline fun <T> ApiResult<T>.errorOnLoading(exception: () -> Exception = { NotFinishedException() }): ApiResult<T>

Makes this result an Error if this result is Loading

Link copied to clipboard
inline fun <T : Any> ApiResult<T?>?.errorOnNull(exception: () -> Exception = { ConditionNotSatisfiedException("Value was null") }): ApiResult<T>

Make this result an Error if Success value was null.

Link copied to clipboard
inline fun <T> ApiResult<T>.errorUnless(exception: (T) -> Exception = { ConditionNotSatisfiedException() }, predicate: (T) -> Boolean): ApiResult<T>

Makes this an Error if predicate returns false

Link copied to clipboard
Link copied to clipboard
infix inline fun <T : Iterable<R>, R> ApiResult<T>.filter(block: (R) -> Boolean): ApiResult<List<R>>

Filter the underlying collection.

@JvmName(name = "filterSequence")
infix inline fun <T : Sequence<R>, R> ApiResult<T>.filter(noinline block: (R) -> Boolean): ApiResult<Sequence<R>>

Filter the underlying sequence.

Link copied to clipboard

Returns only error values

Link copied to clipboard

Filters all null values of results

Link copied to clipboard

Returns only successful values

Link copied to clipboard

Return the first successful value, or an Error if no success was found

Link copied to clipboard

Return the first successful value, or null if no success was found

Link copied to clipboard

Return the first successful value, or throw if no success was found

Link copied to clipboard
infix inline fun <T, R> ApiResult<T>.flatMap(another: (T) -> ApiResult<R>): ApiResult<R>

Call another and if it succeeds, continue with another's result. If it fails, propagate the error. An alias for then.

Link copied to clipboard
@JvmName(name = "flowWithResult")
inline fun <T> ApiResult.Companion.flow(crossinline result: suspend () -> ApiResult<T>): Flow<ApiResult<T>>

Emits ApiResult.Loading, then executes result

Link copied to clipboard
inline fun <T, R> ApiResult<T>.fold(onSuccess: (result: T) -> R, onError: (e: Exception) -> R, noinline onLoading: () -> R? = null): R

Fold this returning the result of onSuccess or onError By default, maps Loading to Error with NotFinishedException

Link copied to clipboard
infix inline fun <T : Iterable<R>, R> ApiResult<T>.ifEmpty(block: () -> Unit): ApiResult<T>

Execute block if this's collection is empty.

Link copied to clipboard
infix inline fun <T, R> ApiResult<T>.map(block: (T) -> R): ApiResult<R>

Change the type of the Success to R without affecting Error/Loading results

Link copied to clipboard
inline fun <T, R> ApiResult<T>.mapEither(success: (T) -> R, error: (Exception) -> Exception): ApiResult<R>

Map both Error and Success. Does not affect Loading

Link copied to clipboard
@JvmName(name = "mapErrorTyped")
infix inline fun <R : Exception, T> ApiResult<T>.mapError(block: (R) -> Exception): ApiResult<T>

Map the exception of the Error state, but only if this exception is of type R. Loading and Success are unaffected

infix inline fun <T> ApiResult<T>.mapError(block: (Exception) -> Exception): ApiResult<T>

Change the exception of the Error response without affecting loading/success results

Link copied to clipboard
infix inline fun <T> Iterable<ApiResult<T>>.mapErrors(transform: (Exception) -> Exception): List<ApiResult<T>>
infix inline fun <T> Sequence<ApiResult<T>>.mapErrors(crossinline transform: (Exception) -> Exception): Sequence<ApiResult<T>>

Maps every Error in this using transform

Link copied to clipboard

Maps the error of the result, if present, to its cause, or self if cause is not available

Link copied to clipboard
infix inline fun <T, R : T> ApiResult<T>.mapLoading(block: () -> R): ApiResult<T>

Maps Loading to a Success, not affecting other states.

Link copied to clipboard
inline fun <T, R> ApiResult<T>.mapOrDefault(default: (e: Exception) -> R, transform: (T) -> R): R

Map the Success result using transform, and if the result is not a success, return default

Link copied to clipboard
inline fun <T, R> Iterable<T>.mapResulting(crossinline map: (T) -> R): List<ApiResult<R>>
inline fun <T, R> Sequence<T>.mapResulting(crossinline map: (T) -> R): Sequence<ApiResult<R>>

Maps each value in the collection, wrapping each map operation in an ApiResult

Link copied to clipboard
infix inline fun <T, R> Iterable<ApiResult<T>>.mapResults(transform: (T) -> R): List<ApiResult<R>>
infix inline fun <T, R> Sequence<ApiResult<T>>.mapResults(crossinline transform: (T) -> R): Sequence<ApiResult<R>>

Maps every item of this using transform

inline fun <T, R> Flow<ApiResult<T>>.mapResults(crossinline transform: suspend (T) -> R): Flow<ApiResult<R>>

Maps each success value of this flow using transform

Link copied to clipboard
infix inline fun <T, R> ApiResult<Iterable<T>>.mapValues(transform: (T) -> R): ApiResult<List<R>>

Executes ApiResult.map on each value of the collection

@JvmName(name = "sequenceMapValues")
infix inline fun <T, R> ApiResult<Sequence<T>>.mapValues(noinline transform: (T) -> R): ApiResult<Sequence<R>>

Executes ApiResult.map on each value of the sequence

Link copied to clipboard
inline fun <T> merge(results: Iterable<ApiResult<T>>): ApiResult<List<T>>

Merges all results into a single List, or if any has failed, returns Error.

Link copied to clipboard
@JvmName(name = "merge2")
inline fun <T> Iterable<ApiResult<T>>.merge(): ApiResult<List<T>>

Merges all results into a single List, or if any has failed, returns Error.

inline fun <T> ApiResult<T>.merge(results: Iterable<ApiResult<T>>): ApiResult<List<T>>

Merges this results and all other results into a single result of type T.

Link copied to clipboard
inline fun <T> ApiResult<T>.nullOnError(): ApiResult<T?>

Maps Error values to nulls

Link copied to clipboard
inline fun <T> Flow<ApiResult<T>>.onEachResult(crossinline block: suspend (T) -> Unit): Flow<ApiResult<T>>

Invokes block each time this flow emits an ApiResult.Success value

Link copied to clipboard
inline fun <T> Flow<ApiResult<T>>.onEachSuccess(crossinline block: suspend (T) -> Unit): Flow<ApiResult<T>>

Invokes block each time this flow emits an ApiResult.Success value

Link copied to clipboard
infix inline fun <T : Iterable<R>, R> ApiResult<T>.onEmpty(block: () -> Unit): ApiResult<T>

Execute block if this's collection is empty.

Link copied to clipboard
@JvmName(name = "onErrorTyped")
infix inline fun <E : Exception, T> ApiResult<T>.onError(block: (E) -> Unit): ApiResult<T>

Invoke a given block if this is Error and it's Error.e is of type E.

infix inline fun <T> ApiResult<T>.onError(block: (Exception) -> Unit): ApiResult<T>

Invoke a given block if this is Error

Link copied to clipboard
infix inline fun <T> ApiResult<T>.onLoading(block: () -> Unit): ApiResult<T>

Invoke given block if this is Loading

Link copied to clipboard
infix inline fun <T> ApiResult<T>.onSuccess(block: (T) -> Unit): ApiResult<T>

Invoke a given block if this is Success

Link copied to clipboard
infix inline fun <T, R : T> ApiResult<T>.or(defaultValue: R): T

If this is Error or Loading, returns defaultValue.

Link copied to clipboard
infix inline fun <T, R : T> ApiResult<T>.orElse(block: (e: Exception) -> R): T

Executes block if this is an ApiResult.Error, otherwise returns ApiResult.value.

Link copied to clipboard
inline fun <T> ApiResult<Set<T>>.orEmpty(): Set<T>
inline fun <T> ApiResult<Sequence<T>>.orEmpty(): Sequence<T>

Returns emptyList if this's collection is empty

inline fun <T> ApiResult<List<T>>.orEmpty(): List<T>

Returns emptyList if this's list is empty

inline fun <K, V> ApiResult<Map<K, V>>.orEmpty(): Map<K, V>

Returns emptyMap if this's map is empty

Link copied to clipboard
fun <T> Flow<ApiResult<T>>.orNull(): Flow<T?>

Maps this flow to an ApiResult.Success value, otherwise the value is null

inline fun <T> ApiResult<T>?.orNull(): T?
Link copied to clipboard
fun <T> Flow<ApiResult<T>>.orThrow(): Flow<T>

Maps this flow to an ApiResult.Success value, otherwise throws the resulting error

inline fun <T> ApiResult<T>.orThrow(): T

Throws ApiResult.Error.e, or NotFinishedException if the request has not been completed yet.

Link copied to clipboard
@JvmName(name = "recoverTyped")
infix inline fun <T : Exception, R> ApiResult<R>.recover(another: (e: T) -> ApiResult<R>): ApiResult<R>

Recover from an exception of type R, else no-op. Does not affect Loading.

infix inline fun <T> ApiResult<T>.recover(another: (e: Exception) -> ApiResult<T>): ApiResult<T>

Recover from an exception. Does not affect Loading See also the typed version of this function to recover from a specific exception type

Link copied to clipboard
inline fun <T> ApiResult<T>.recoverIf(condition: (Exception) -> Boolean, block: (Exception) -> ApiResult<T>): ApiResult<T>

Recover from an Error only if the condition is true, else no-op. Does not affect Loading

Link copied to clipboard
inline fun <T> ApiResult<T>.require(): T

Alias for orThrow

inline fun <T> ApiResult<T>.require(message: (T) -> String? = { null }, predicate: (T) -> Boolean): ApiResult<T>

Makes this an error with ConditionNotSatisfiedException using specified message if the predicate returns false.

Link copied to clipboard
inline fun <R, T> ApiResult<T>.requireIs(exception: (T) -> Exception = { value -> "Result value is of type ${value?.let { it::class.simpleName }} but expected ${R::class.simpleName}" .let(::ConditionNotSatisfiedException) }): ApiResult<R>
Link copied to clipboard
inline fun <T> ApiResult<T?>?.requireNotNull(message: () -> String = { "ApiResult value was null" }): ApiResult<T & Any>

Alias for errorOnNull

Link copied to clipboard
inline fun <T : Exception, R> ApiResult<R>.rethrow(): ApiResult<R>

Throws if this result is an Error and Error.e is of type T. Ignores all other exceptions.

Link copied to clipboard

Throws CancellationExceptions if this is an Error.

Link copied to clipboard
inline fun <T> runResulting(block: () -> T): ApiResult<T>

Executes block, wrapping it in an ApiResult

Link copied to clipboard
inline fun <T, R> T.runResulting(block: T.() -> R): ApiResult<R>

Execute block wrapping it in an ApiResult

Link copied to clipboard
inline suspend fun <T> SuspendResult(context: CoroutineContext = EmptyCoroutineContext, noinline block: suspend CoroutineScope.() -> T): ApiResult<T>

Run block with a given context, catching any exceptions both in the block and nested coroutines. block will not return until all nested launched coroutines, if any, return. For the other type of behavior, use ApiResult.invoke directly. A failure of a child does not cause the scope to fail and does not affect its other children. A failure of the scope itself (exception thrown in the block or external cancellation) fails the result with all its children, but does not cancel parent job.

Link copied to clipboard
infix inline fun <T, R> ApiResult<T>.then(another: (T) -> ApiResult<R>): ApiResult<R>

Call another and if it succeeds, continue with another's result. If it fails, propagate the error. Effectively, flatMap to another result.

Link copied to clipboard
infix inline fun <T> ApiResult<T>.tryChain(block: (T) -> Unit): ApiResult<T>

Call block, wrapping it in an ApiResult, and then discard the Success value, but propagate Errors.

Link copied to clipboard
inline fun <T> ApiResult.Companion.tryFlow(crossinline call: suspend () -> T): Flow<ApiResult<T>>

Emits ApiResult.Loading, then executes call and wraps it.

Link copied to clipboard
infix inline fun <T, R> ApiResult<T>.tryMap(block: (T) -> R): ApiResult<R>

Change the type of successful result to R, also wrapping block in another result then folding it (handling exceptions)

Link copied to clipboard
@JvmName(name = "tryRecoverTyped")
infix inline fun <T : Exception, R> ApiResult<R>.tryRecover(block: (T) -> R): ApiResult<R>

calls recover catching and wrapping any exceptions thrown inside block.

infix inline fun <T> ApiResult<T>.tryRecover(block: (e: Exception) -> T): ApiResult<T>

Calls recover catching and wrapping any exceptions thrown inside block.

Link copied to clipboard
inline fun <T> ApiResult<T>.tryRecoverIf(condition: (Exception) -> Boolean, block: (Exception) -> T): ApiResult<T>

Recover from an Error only if the condition is true, else no-op. Does not affect Loading

Link copied to clipboard
inline fun ApiResult<*>.unit(): ApiResult<Unit>

Map this result to Unit, discarding the value

Link copied to clipboard
inline fun <T> ApiResult<ApiResult<T>>.unwrap(): ApiResult<T>

Unwrap an ApiResult<ApiResult<T>> to become ApiResult<T>

Link copied to clipboard
inline fun <T> Iterable<ApiResult<T>>.values(): List<T>

Returns a list of only successful values, discarding any errors