Package-level declarations

Types

Link copied to clipboard
sealed class AsyncResult<out S>

Models the state of an asynchronous operation.

Link copied to clipboard
@ObjCName(name = "AsyncError")
data class Error(val throwable: Throwable? = null, metadata: Any? = null, val errorId: ErrorId? = null) : AsyncResult<Nothing>

The modeled request failed. If there was anything thrown to cause this, it'll be included in throwable. It might also contain some extra metadata, typically used to provide context about the failure, to help make it actionable (either for the user or the developer). An optional errorId can be provided for error tracking and correlation purposes.

Link copied to clipboard
@ObjCName(name = "AsyncErrorId")
value class ErrorId(val value: String)

A unique identifier for error tracking and correlation.

Link copied to clipboard
sealed interface Incomplete

Marks any AsyncResult that hasn't yet delivered a result (Success or Error). Useful to bundle NotStarted and Loading states in exhaustive when statements.

Link copied to clipboard

Used to model in-flight operations. For example, if a request is user initiated, it'll be in this state since the user initiated it up until it's either Success or Error.

Link copied to clipboard

Used to model idle states. For example, if an operation is user initiated, it'll remain in this state until the user starts it (when it'll likely transition to Loading).

Link copied to clipboard
interface ResultFlowScope<in T>

Scope for the resultFlow builder. Provides explicit emission functions for each AsyncResult state: success, error, loading, and notStarted.

Link copied to clipboard
interface ResultScope

Scope for the result DSL block. Provides bind, error, loading, notStarted, ensure, and ensureNotNull for short-circuit evaluation of AsyncResult values.

Link copied to clipboard
data class Success<out S>(val value: S) : AsyncResult<S>

A successful request, containing the resulting value.

Link copied to clipboard
class UnwrapException(message: String) : Exception

Properties

Link copied to clipboard

Returns true if the AsyncResult is Error, false otherwise.

Link copied to clipboard

Returns true if the AsyncResult is Incomplete, false otherwise.

Link copied to clipboard

Returns true if the AsyncResult is Success, false otherwise.

Functions

Link copied to clipboard
inline fun <R> AsyncResult<R>.and(result: AsyncResult<R>): AsyncResult<R>

Returns the result if the receiver is Success.

Link copied to clipboard
inline fun <R, T> AsyncResult<R>.andThen(noinline transform: (R) -> AsyncResult<T>): AsyncResult<T>

Returns the transform result value if both the receiver and the transformed value are Success.

inline fun <T1, T2> () -> AsyncResult<T1>.andThen(noinline transform: (T1) -> AsyncResult<T2>): AsyncResult<T2>

Returns the transform result value if the receiver function returned a Success value. This value will be passed to the transform function.

Link copied to clipboard
inline fun anyError(vararg lcrs: AsyncResult<*>): Boolean

Returns true if any of the given AsyncResult items is an Error.

Link copied to clipboard
inline fun anyIncomplete(vararg lcrs: AsyncResult<*>): Boolean

Returns true if any of the given AsyncResult items is Incomplete.

Link copied to clipboard

Returns true if any of the AsyncResult instances are Incomplete.

Link copied to clipboard
inline fun anyLoading(vararg lcrs: AsyncResult<*>): Boolean

Returns true if any of the given AsyncResult items is Loading.

Link copied to clipboard

Returns true if any of the AsyncResult instances are Loading.

Link copied to clipboard
fun <T> Flow<T>.asAsyncResult(startWithLoading: Boolean = true): Flow<AsyncResult<T>>

Transforms a Flow of values into a Flow of AsyncResult, wrapping each emitted value in a Success and handling errors by wrapping them in Error.

Link copied to clipboard
inline fun <R, T> AsyncResult<R>.bimap(success: (R) -> T, error: (Error) -> Error): AsyncResult<T>

Transforms both Success and Error cases simultaneously.

Link copied to clipboard

Caches the latest Success value and keeps emitting it instead of Loading during reloads.

Link copied to clipboard
inline fun <T> Incomplete.cast(): AsyncResult<T>

Converts Loading and NotStarted to a AsyncResult of type T. This is to prevent us to having to map everything when we know we don't have a Success value, where types would actually matter.

Link copied to clipboard
inline fun <R> AsyncResult<*>.castOrError(noinline lazyMetadata: () -> Any?? = null): AsyncResult<R>

Converts the current AsyncResult to a AsyncResult of type R if the current value is of type R. If the current value is not of type R, it will return an Error.

Link copied to clipboard

Combines an Iterable of AsyncResult items into a single AsyncResult containing a List.

Combines a List of AsyncResult items into a single AsyncResult containing a List.

Combines a Sequence of AsyncResult items into a single AsyncResult containing a List.

Link copied to clipboard
@JvmName(name = "component1Pair")
inline operator fun <T> AsyncResult<Pair<T, *>>.component1(): AsyncResult<T>
@JvmName(name = "component1Triple")
inline operator fun <T> AsyncResult<Triple<T, *, *>>.component1(): AsyncResult<T>
Link copied to clipboard
@JvmName(name = "component2Pair")
inline operator fun <T> AsyncResult<Pair<*, T>>.component2(): AsyncResult<T>
@JvmName(name = "component2Triple")
inline operator fun <T> AsyncResult<Triple<*, T, *>>.component2(): AsyncResult<T>
Link copied to clipboard
@JvmName(name = "component3Triple")
inline operator fun <T> AsyncResult<Triple<*, *, T>>.component3(): AsyncResult<T>
Link copied to clipboard
inline operator fun <T> AsyncResult<T>.contains(value: T): Boolean

Returns true if this AsyncResult is a Success containing the given value.

Link copied to clipboard
suspend fun <T> ResultFlowScope<T>.error(throwable: Throwable, errorId: ErrorId? = null)

Emits an Error wrapping the given throwable and optional errorId.

fun ResultScope.error(error: Throwable, errorId: ErrorId? = null): Nothing

Short-circuits with Error wrapping the given error and optional errorId.

Link copied to clipboard
inline fun <R> AsyncResult<R>.errorIdOrNull(): ErrorId?

Returns the ErrorId if the AsyncResult is Error and has an errorId, else returns null.

Link copied to clipboard
inline fun <R> AsyncResult<R>.errorOrNull(): Error?

Returns the Error itself if the AsyncResult is Error else returns null.

Link copied to clipboard
inline fun Array<out AsyncResult<*>>.errors(): List<Error>

Returns a list of all the Errors from an array of AsyncResult items.

inline fun Iterable<AsyncResult<*>>.errors(): List<Error>

Returns a list of all the Errors from a list of AsyncResult items.

inline fun Sequence<AsyncResult<*>>.errors(): List<Error>

Returns a list of all the Errors from a sequence of AsyncResult items.

Link copied to clipboard
inline fun errorsFrom(vararg lcrs: AsyncResult<*>): List<Error>

Returns a list of all the Errors from the given AsyncResult items.

Link copied to clipboard
@ObjCName(name = "AsyncErrorWithId")
inline fun ErrorWithId(errorId: ErrorId, metadata: Any? = null): Error

Creates an Error object with the given errorId and optional metadata.

Link copied to clipboard
@ObjCName(name = "AsyncErrorWithMetadata")
inline fun ErrorWithMetadata(metadata: Any, errorId: ErrorId? = null): Error

Creates an Error object with the given metadata and optional errorId.

Link copied to clipboard
suspend fun <T> ResultFlowScope<T>.errorWithMetadata(metadata: Any, errorId: ErrorId? = null)

Emits an Error carrying typed metadata and optional errorId.

fun <T> ResultScope.errorWithMetadata(metadata: T, errorId: ErrorId? = null): Nothing

Short-circuits with an Error carrying typed metadata.

Link copied to clipboard

Returns the metadata value from the Error if the AsyncResult is Error, and has metadata or the requested type.

Link copied to clipboard
inline fun <R> AsyncResult<R>.expect(crossinline message: () -> Any): R

Extracts the value from the AsyncResult if it's a Success, otherwise throws an UnwrapException with the computed message in it.

Link copied to clipboard
inline fun AsyncResult<*>.expectError(crossinline message: () -> Any): Error

Extracts the value from the AsyncResult if it's an Error, otherwise throws an UnwrapException with the computed message in it.

Link copied to clipboard
inline fun AsyncResult<*>.expectErrorId(crossinline message: () -> Any): ErrorId

Extracts the ErrorId from the AsyncResult if it's an Error with an ErrorId, otherwise throws an UnwrapException with the computed message in it.

Link copied to clipboard
inline fun <M> AsyncResult<*>.expectMetadata(crossinline message: () -> Any): M

Extracts the metadata from the AsyncResult if it's an Error with the metadata of type M, otherwise throws an UnwrapException with the computed message in it.

Link copied to clipboard
inline fun AsyncResult<*>.expectThrowable(crossinline message: () -> Any): Throwable

Extracts the value from the AsyncResult if it's an Error with a Throwable in it, otherwise throws an UnwrapException with the computed message in it.

Link copied to clipboard
fun <R> Flow<AsyncResult<R>>.filterNotLoading(): Flow<AsyncResult<R>>

Alias for skipWhileLoading. Filters out all Loading emissions from this flow.

Link copied to clipboard
inline fun <R> AsyncResult<R>.filterOrError(noinline lazyMetadata: () -> Any?? = null, predicate: (R) -> Boolean): AsyncResult<R>

Returns the current AsyncResult if it matches the given predicate, or an Error if it does not.

Link copied to clipboard
inline fun <R, T> AsyncResult<R>.flatMap(transform: (R) -> AsyncResult<T>): AsyncResult<T>

Transforms the current AsyncResult to the result of transform if it's a Success, based on its contained value.

Link copied to clipboard

Unwraps the AsyncResult inside of the AsyncResult.

Link copied to clipboard
inline fun <R, T> AsyncResult<R>.fold(ifNotStarted: () -> T, ifLoading: () -> T, ifSuccess: (R) -> T, ifError: (Error) -> T): T

Generates a value of type T from any state contained in AsyncResult.

Link copied to clipboard

Returns a list of all the Errors from a list of AsyncResult items.

Link copied to clipboard

Returns a list of all the Throwables inside of Errors from a list of AsyncResult items.

Link copied to clipboard
inline fun <R> AsyncResult<R>.getOrDefault(default: R): R

Returns the value if the AsyncResult is Success else returns the default value.

Link copied to clipboard
inline fun <R> AsyncResult<R>.getOrElse(transform: (AsyncResult<R>) -> R): R

Returns the value if the AsyncResult is Success else returns the result of the transform function.

inline suspend fun <R> Flow<AsyncResult<R>>.getOrElse(noinline transform: (Error) -> R): R

Obtains the first terminal value of the flow, and if it is a Success, it returns the encapsulated value. Otherwise, it returns the result of the given transform function.

Link copied to clipboard
inline fun <R> AsyncResult<List<R>>.getOrEmpty(): List<R>

Returns the value if the AsyncResult is Success else returns an empty list.

inline fun <K, V> AsyncResult<Map<K, V>>.getOrEmpty(): Map<K, V>

Returns the value if the AsyncResult is Success else returns an empty map.

Link copied to clipboard
inline fun <R> AsyncResult<R>.getOrNull(): R?

Returns the value if the AsyncResult is Success else returns null.

inline suspend fun <R> Flow<AsyncResult<R>>.getOrNull(): R?

Obtains the first terminal value of the flow, and if it is a Success, it returns the encapsulated value. Otherwise, it returns null.

Link copied to clipboard
inline fun <R> AsyncResult<R>.getOrThrow(): R

Returns the value if the AsyncResult is Success else returns null.

inline suspend fun <R> Flow<AsyncResult<R>>.getOrThrow(): R

Obtains the first terminal value of the flow, and if it is a Success, it returns the encapsulated value. Otherwise, it throws an exception.

Link copied to clipboard

Returns a list of Incomplete items (Loading and NotStarted) from an Array of AsyncResult items.

Returns a list of Incomplete items (Loading and NotStarted) from a list of AsyncResult items.

Returns a list of Incomplete items (Loading and NotStarted) from a Sequence of AsyncResult items.

Link copied to clipboard
inline fun <T> AsyncResult<T>.isErrorAnd(predicate: (Throwable?) -> Boolean): Boolean

Returns true if the AsyncResult is Error and the predicate returns true for the throwable.

Link copied to clipboard
inline fun <T, E> AsyncResult<T>.isErrorWithMetadataAnd(predicate: (Throwable?, E?) -> Boolean): Boolean

Returns true if the AsyncResult is Error and the predicate returns true for the throwable and metadata.

Link copied to clipboard
inline fun <T> AsyncResult<T>.isSuccessAnd(predicate: (T) -> Boolean): Boolean

Returns true if the AsyncResult is Success and the predicate returns true for the success value.

Link copied to clipboard
inline fun <R, T> AsyncResult<R>.map(transform: (AsyncResult<R>) -> AsyncResult<T>): AsyncResult<T>

Transforms the current AsyncResult to the result of transform.

Link copied to clipboard
inline fun <R> AsyncResult<R>.mapError(transform: (Error) -> Error): AsyncResult<R>

Transforms the Error value, if any, via transform.

Link copied to clipboard
inline fun <R, T> AsyncResult<R>.mapSuccess(transform: (R) -> T): AsyncResult<T>

Transforms the Success value via transform. The AsyncResult will change its containing type accordingly.

Link copied to clipboard
@JvmName(name = "iterableMetadata")
inline fun <T> Iterable<AsyncResult<Error>>.metadata(): List<T>

Returns a list of metadata objects of type T from Errors in a list of AsyncResult items.

inline fun <T> Iterable<Error>.metadata(): List<T>

Returns a list of metadata objects of type T from a list of Error items.

Link copied to clipboard
inline fun <R> AsyncResult<R>.onError(block: (Throwable?) -> Unit): AsyncResult<R>

Runs the block when the result is Error.

fun <R> Flow<AsyncResult<R>>.onError(action: suspend (Error) -> Unit): Flow<AsyncResult<R>>

It invokes the given action before each value of the upstream flow is emitted downstream, IF the emitted value is Error.

Link copied to clipboard
inline fun <R, M> AsyncResult<R>.onErrorWithMetadata(block: (throwable: Throwable?, metadata: M?) -> Unit): AsyncResult<R>

Runs the block when the result is Error and has metadata of type M.

Link copied to clipboard
inline fun <R> AsyncResult<R>.onIncomplete(block: () -> Unit): AsyncResult<R>

Runs the block when the result is Incomplete (Loading or NotStarted).

fun <R> Flow<AsyncResult<R>>.onIncomplete(action: suspend () -> Unit): Flow<AsyncResult<R>>

It invokes the given action before each value of the upstream flow is emitted downstream, IF the emitted value is Incomplete (Loading or NotStarted).

Link copied to clipboard
inline fun <R> AsyncResult<R>.onLoading(block: () -> Unit): AsyncResult<R>

Runs the block when the result is Loading.

fun <R> Flow<AsyncResult<R>>.onLoading(action: suspend () -> Unit): Flow<AsyncResult<R>>

It invokes the given action before each value of the upstream flow is emitted downstream, IF the emitted value is Loading.

Link copied to clipboard
inline fun <R> AsyncResult<R>.onNotStarted(block: () -> Unit): AsyncResult<R>

Runs the block when the result is NotStarted.

Link copied to clipboard
inline fun <R> AsyncResult<R>.onSuccess(block: (R) -> Unit): AsyncResult<R>

Runs the block when the value is Success.

fun <R> Flow<AsyncResult<R>>.onSuccess(action: suspend (R) -> Unit): Flow<AsyncResult<R>>

It invokes the given action before each value of the upstream flow is emitted downstream, IF the emitted value is Success.

Link copied to clipboard
inline fun <R> AsyncResult<R>.or(other: AsyncResult<R>): AsyncResult<R>

Returns other if this is an Error, otherwise returns this unchanged.

Link copied to clipboard
inline fun <R> AsyncResult<R>.orElse(transform: (Error) -> AsyncResult<R>): AsyncResult<R>

Returns the result of transform if this is an Error, otherwise returns this unchanged.

Link copied to clipboard
inline fun <R> AsyncResult<R?>.orError(noinline lazyMetadata: () -> Any?? = null): AsyncResult<R>

Transforms the type of AsyncResult from nullable to non-nullable. If the value is null, it will return an Error. It also allows adding specific metadata to disambiguate errors if necessary, via lazyMetadata.

Link copied to clipboard
inline fun <T> Array<out AsyncResult<T>>.partition(): Pair<List<T>, List<Error>>

Partitions an array of AsyncResult items into successful values and errors.

Partitions a collection of AsyncResult items into successful values and errors.

Partitions a sequence of AsyncResult items into successful values and errors.

Link copied to clipboard
infix inline operator fun Error.plus(errorId: ErrorId): Error

Adds the given errorId to the Error object, preserving metadata.

infix inline operator fun Error.plus(metadata: Any): Error

Adds the given metadata to the Error object, preserving errorId.

Link copied to clipboard
inline fun <R> AsyncResult<R>.recover(transform: (Error) -> R): AsyncResult<R>

Converts an Error to a Success by applying transform to the error.

Link copied to clipboard
inline fun <R, E : Any> AsyncResult<R>.recoverIf(transform: (E) -> R): AsyncResult<R>

Converts an Error to a Success only if the error metadata matches type E.

Link copied to clipboard
inline fun <T> result(block: ResultScope.() -> T): AsyncResult<T>

Monad comprehension DSL for AsyncResult.

Link copied to clipboard
fun <T> resultFlow(block: suspend ResultFlowScope<T>.() -> Unit): Flow<AsyncResult<T>>

Creates a Flow of AsyncResult with a DSL that provides explicit success, error, loading, and notStarted emissions.

Link copied to clipboard
fun <R> Flow<AsyncResult<R>>.retryOnError(maxRetries: Int = 3, delay: Duration = Duration.ZERO, predicate: (Error) -> Boolean = { true }): Flow<AsyncResult<R>>

Retries collecting from the upstream flow when an Error is emitted.

Link copied to clipboard
inline fun <R, E : Any> Flow<AsyncResult<R>>.retryOnErrorWithMetadata(maxRetries: Int = 3, delay: Duration = Duration.ZERO, crossinline predicate: (E) -> Boolean = { true }): Flow<AsyncResult<R>>

Retries collecting from the upstream flow when an Error with metadata of type E is emitted.

Link copied to clipboard

Alias for combine. Converts a List of AsyncResult items into a single AsyncResult containing a List.

Link copied to clipboard
fun <R> Flow<AsyncResult<R>>.skipWhileLoading(): Flow<AsyncResult<R>>

Filters out all Loading emissions from this flow, only emitting NotStarted, Success, or Error values.

Link copied to clipboard
Link copied to clipboard
inline fun <T> Array<out AsyncResult<T>>.successes(): List<T>

Returns all Success values from an array of AsyncResult items.

inline fun <T> Iterable<AsyncResult<T>>.successes(): List<T>

Returns all Success values from a list of AsyncResult items.

inline fun <T> Sequence<AsyncResult<T>>.successes(): List<T>

Returns all Success values from a sequence of AsyncResult items.

Link copied to clipboard

Returns the throwable if the AsyncResult is Error else returns null.

Link copied to clipboard
inline fun Array<out AsyncResult<*>>.throwables(): List<Throwable>

Returns a list of all the Throwables inside of Errors from an Array of AsyncResult items.

Returns a list of all the Throwables inside of Errors from a list of AsyncResult items.

Returns a list of all the Throwables inside of Errors from a Sequence of AsyncResult items.

Link copied to clipboard
fun <R> Flow<AsyncResult<R>>.timeoutToError(timeout: Duration, error: () -> Error): Flow<AsyncResult<R>>

Emits an Error if no terminal state (Success or Error) is received within the specified timeout duration.

Link copied to clipboard
inline fun <T> AsyncResult<T>.toErrorIf(predicate: (T) -> Boolean, error: (T) -> Error = { Error.Empty }): AsyncResult<T>

Converts a Success to an Error if the predicate returns true for the success value. Other states (Loading, NotStarted, Error) are returned unchanged.

Link copied to clipboard
inline fun <T> AsyncResult<T>.toErrorUnless(predicate: (T) -> Boolean, error: (T) -> Error = { Error.Empty }): AsyncResult<T>

Converts a Success to an Error if the predicate returns false for the success value. This is the inverse of toErrorIf. Other states (Loading, NotStarted, Error) are returned unchanged.

Link copied to clipboard
inline fun <R> AsyncResult<R>.unwrap(): R

Extracts the value from the AsyncResult if it's a Success, otherwise throws an UnwrapException.

Link copied to clipboard
inline fun AsyncResult<*>.unwrapError(): Error

Extracts the value from the AsyncResult if it's an Error, otherwise throws an UnwrapException.

Link copied to clipboard

Extracts the ErrorId from the AsyncResult if it's an Error with an ErrorId, otherwise throws an UnwrapException.

Link copied to clipboard
inline fun <M> AsyncResult<*>.unwrapMetadata(): M

Extracts the metadata from the AsyncResult if it's an Error with metadata of type M, otherwise throws an UnwrapException.

Link copied to clipboard

Extracts the value from the AsyncResult if it's an Error with a Throwable, otherwise throws an UnwrapException.

Link copied to clipboard
inline fun <R1, R2, T> zip(crossinline result1: () -> AsyncResult<R1>, crossinline result2: () -> AsyncResult<R2>, crossinline transform: (R1, R2) -> T): AsyncResult<T>

Combines two AsyncResults (result1 and result2) into a single one, by applying the transform to their values.

inline fun <R1, R2, R3, T> zip(crossinline result1: () -> AsyncResult<R1>, crossinline result2: () -> AsyncResult<R2>, crossinline result3: () -> AsyncResult<R3>, crossinline transform: (R1, R2, R3) -> T): AsyncResult<T>

Combines three AsyncResults (result1, result2, and result3) into a single one, by applying the transform to their values.

inline fun <R1, R2, R3, R4, T> zip(crossinline result1: () -> AsyncResult<R1>, crossinline result2: () -> AsyncResult<R2>, crossinline result3: () -> AsyncResult<R3>, crossinline result4: () -> AsyncResult<R4>, crossinline transform: (R1, R2, R3, R4) -> T): AsyncResult<T>

Combines four AsyncResults (result1, result2, result3, and result4) into a single one, by applying the transform to their values.

Link copied to clipboard
inline fun <R1, R2, T> AsyncResult<R1>.zipWith(result: AsyncResult<R2>, crossinline transform: (R1, R2) -> T): AsyncResult<T>

Combines two AsyncResults (the receiver and result) into a single one, by applying the transform to their values.

inline fun <R1, R2, T> () -> AsyncResult<R1>.zipWith(crossinline producer: () -> AsyncResult<R2>, crossinline transform: (R1, R2) -> T): AsyncResult<T>

Combines two AsyncResults (the receiver lambda result and the producer lambda) into a single one, by applying the transform to their values.

inline fun <R1, R2, R3, T> AsyncResult<R1>.zipWith(result1: AsyncResult<R2>, result2: AsyncResult<R3>, crossinline transform: (R1, R2, R3) -> T): AsyncResult<T>

Combines three AsyncResults (the receiver, result1, and result2) into a single one, by applying the transform to their values.

inline fun <R1, R2, R3, T> () -> AsyncResult<R1>.zipWith(crossinline producer1: () -> AsyncResult<R2>, crossinline producer2: () -> AsyncResult<R3>, crossinline transform: (R1, R2, R3) -> T): AsyncResult<T>

Combines three AsyncResults (the receiver lambda result, producer1, and producer2) into a single one, by applying the transform to their values.

inline fun <R1, R2, R3, R4, T> AsyncResult<R1>.zipWith(result1: AsyncResult<R2>, result2: AsyncResult<R3>, result3: AsyncResult<R4>, crossinline transform: (R1, R2, R3, R4) -> T): AsyncResult<T>

Combines four AsyncResults (the receiver, result1, result2, and result3) into a single one, by applying the transform to their values.

inline fun <R1, R2, R3, R4, T> () -> AsyncResult<R1>.zipWith(crossinline producer1: () -> AsyncResult<R2>, crossinline producer2: () -> AsyncResult<R3>, crossinline producer3: () -> AsyncResult<R4>, crossinline transform: (R1, R2, R3, R4) -> T): AsyncResult<T>

Combines four AsyncResults (the receiver lambda result, producer1, producer2, and producer3) into a single one, by applying the transform to their values.