TryResult.kt
package de.pflugradts.kotlinextensions
import de.pflugradts.kotlinextensions.TryResult.Companion.failure
import de.pflugradts.kotlinextensions.TryResult.Companion.success
inline fun <R> tryCatching(block: () -> R) = runCatching(block).fold(
onSuccess = { success(it) },
onFailure = { ex ->
when (ex) {
is Exception -> failure(ex)
else -> throw ex
}
},
)
private class Failure(val ex: Exception)
@JvmInline
value class TryResult<R> private constructor(
val value: Any?,
) {
val failure: Boolean get() = value is Failure
val success: Boolean get() = value !is Failure
fun exceptionOrNull() = when (value) {
is Failure -> value.ex
else -> null
}
@Suppress("UNCHECKED_CAST")
fun getOrNull() = when (value) {
is Failure -> null
else -> value as R
}
infix fun getOrElse(other: R) = getOrNull() ?: other
fun onFailure(action: (ex: Exception) -> Unit) = apply { exceptionOrNull()?.let(action) }
fun onSuccess(action: (value: R) -> Unit) = apply { getOrNull()?.let(action) }
fun <T> map(fn: (R) -> T): TryResult<T> = if (success) success(fn(getOrNull()!!)) else failure(exceptionOrNull()!!)
fun retry(block: (TryResult<R>) -> TryResult<R>) = if (failure) block(this) else this
companion object {
fun <R> success(value: R) = TryResult<R>(value)
fun <R> failure(ex: Exception) = TryResult<R>(Failure(ex))
}
}