commonMain.io.kotest.fp.Try.kt Maven / Gradle / Ivy
package io.kotest.fp
sealed class Try {
data class Success(val value: T) : Try()
data class Failure(val error: Throwable) : Try()
companion object {
operator fun invoke(t: Throwable): Try = Failure(t)
inline operator fun invoke(f: () -> T): Try = try {
Success(f())
} catch (e: Throwable) {
println(e)
if (nonFatal(e)) Failure(e) else throw e
}
}
inline fun map(f: (T) -> U): Try = flatMap {
Try { f(it) }
}
fun isSuccess() = this is Success
fun isFailure() = this is Failure
fun getOrThrow(): T = when (this) {
is Failure -> throw error
is Success -> value
}
inline fun flatMap(f: (T) -> Try): Try = when (this) {
is Failure -> this
is Success -> f(value)
}
inline fun fold(ifFailure: (Throwable) -> R, ifSuccess: (T) -> R): R = when (this) {
is Failure -> ifFailure(this.error)
is Success -> ifSuccess(this.value)
}
inline fun onFailure(f: (Throwable) -> Unit): Try = when (this) {
is Success -> this
is Failure -> {
f(this.error)
this
}
}
inline fun onSuccess(f: (T) -> Unit): Try = when (this) {
is Success -> {
f(this.value)
this
}
is Failure -> this
}
fun toOption(): Option = fold({ Option.None }, {
Option.Some(
it
)
})
inline fun mapFailure(f: (Throwable) -> Throwable) = fold({ f(it).failure() }, { it.success() })
fun getOrNull(): T? = fold({ null }, { it })
}
fun Try>.flatten(): Try = when (this) {
is Try.Success -> this.value
is Try.Failure -> this
}
inline fun Try.getOrElse(f: (Throwable) -> U): U = when (this) {
is Try.Success -> this.value
is Try.Failure -> f(this.error)
}
inline fun Try.recoverWith(f: (Throwable) -> Try): Try = when (this) {
is Try.Success -> this
is Try.Failure -> f(this.error)
}
fun Try.recover(f: (Throwable) -> U): Try = when (this) {
is Try.Success -> this
is Try.Failure -> Try { f(this.error) }
}
fun T.success(): Try = Try.Success(this)
fun Throwable.failure(): Try = Try.Failure(this)
expect fun nonFatal(t: Throwable): Boolean