Skip to content

Instantly share code, notes, and snippets.

@seanghay
Created August 27, 2020 04:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seanghay/34466426dd2036bbd05c414c1359ba68 to your computer and use it in GitHub Desktop.
Save seanghay/34466426dd2036bbd05c414c1359ba68 to your computer and use it in GitHub Desktop.
ResultOf is a utility result class for handling data and exception.
/**
* ResultOf is a utility result class for handling data and exception.
* It's useful for LiveData and fragment/activity communication.
*/
sealed class ResultOf<out T> {
data class Success<out T>(val value: T) : ResultOf<T>()
data class Failure(
val message: String?,
val throwable: Throwable?
) : ResultOf<Nothing>()
}
@Suppress("NOTHING_TO_INLINE")
inline fun <T> T.asSuccess(): ResultOf.Success<T> {
return ResultOf.Success(this)
}
@Suppress("NOTHING_TO_INLINE")
inline fun <T : Throwable> T.asFailure(message: String? = null): ResultOf.Failure {
return ResultOf.Failure(message, this)
}
fun <T> Result<T>.asResultOf(): ResultOf<T> {
if (isSuccess) return ResultOf.Success(getOrThrow())
return ResultOf.Failure(null, exceptionOrNull())
}
inline fun <T> ResultOf<T>.onSuccess(block: (T) -> Unit) {
if (this is ResultOf.Success) {
block(this.value)
}
}
inline fun <T> ResultOf<T>.onFailure(block: (String?, Throwable?) -> Unit) {
if (this is ResultOf.Failure) {
block(message, throwable)
}
}
inline fun <T, R> ResultOf<T>.map(transform: (T) -> R): ResultOf<R> {
return when (this) {
is ResultOf.Success -> ResultOf.Success(transform(value))
is ResultOf.Failure -> this
}
}
inline fun <T, R> ResultOf<T>.mapNotNull(transform: (T) -> R?): ResultOf<R> {
return when (this) {
is ResultOf.Success -> ResultOf.Success(transform(value)).failureWhenNull()
is ResultOf.Failure -> this
}
}
@Suppress("NOTHING_TO_INLINE")
inline fun <T> ResultOf<T?>.failureWhenNull(): ResultOf<T> {
return when (this) {
is ResultOf.Failure -> this
is ResultOf.Success -> if (value == null)
ResultOf.Failure(null, IllegalStateException("value is null"))
else ResultOf.Success(value)
}
}
@Suppress("NOTHING_TO_INLINE")
inline fun <T> ResultOf<T>.getOrDefault(default: T): T {
return when (this) {
is ResultOf.Success -> value
is ResultOf.Failure -> default
}
}
inline fun <T> ResultOf<T>.getOrDefault(block: () -> T): T {
return when (this) {
is ResultOf.Success -> value
is ResultOf.Failure -> block()
}
}
@Suppress("NOTHING_TO_INLINE")
inline fun <T> ResultOf<T>.getOrNull(): T? {
if (this is ResultOf.Success) {
return value
}
return null
}
@Suppress("NOTHING_TO_INLINE")
inline fun <T> ResultOf<T>.getOrThrow(): T {
return when (this) {
is ResultOf.Success -> value
is ResultOf.Failure -> if (throwable == null) throw IllegalStateException(message)
else throw throwable
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment