com.avito.android.Result.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of result Show documentation
Show all versions of result Show documentation
Collection of infrastructure libraries and gradle plugins of Avito Android project
The newest version!
package com.avito.android
import com.avito.composite_exception.CompositeException
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
/**
* Why not [kotlin.Result]?
* - It's usage as return type is experimental before Kotlin 1.5
* [KEEP](https://github.com/Kotlin/KEEP/blob/master/proposals/stdlib/result.md#limitations)
* - it requires to enable special compiler option to go without error
* - it sometimes exposed in modules API, which will require clients to enable this compiler options
*
* Could be replaced with [kotlin.Result] as it's return type usage matures to stable
*/
public sealed class Result {
public fun getOrThrow(): T = when (this) {
is Success -> value
is Failure -> throw throwable
}
public fun getOrElse(func: (Throwable) -> T): T = when (this) {
is Success -> value
is Failure -> func(throwable)
}
public inline fun map(
mapSuccess: (value: T) -> R
): Result = when (this) {
is Success -> try {
Success(mapSuccess(value))
} catch (throwable: Throwable) {
Failure(throwable)
}
is Failure -> Failure(throwable)
}
public inline fun flatMap(
mapSuccess: (value: T) -> Result
): Result = when (this) {
is Success -> try {
mapSuccess(value)
} catch (e: Throwable) {
Failure(e)
}
is Failure -> Failure(throwable)
}
public inline fun fold(onSuccess: (value: T) -> R, onFailure: (throwable: Throwable) -> R): R = when (this) {
is Success -> onSuccess(value)
is Failure -> onFailure(throwable)
}
public inline fun recover(func: (Throwable) -> T): Result = when (this) {
is Success -> this
is Failure -> try {
Success(func(throwable))
} catch (t: Throwable) {
Failure(t)
}
}
public inline fun rescue(f: (Throwable) -> Result): Result = when (this) {
is Success -> this
is Failure -> try {
f(throwable)
} catch (t: Throwable) {
Failure(t)
}
}
public inline fun exists(predicate: (T) -> Boolean): Boolean = when (this) {
is Success -> try {
predicate(getOrThrow())
} catch (e: Throwable) {
false
}
is Failure -> false
}
public inline fun onSuccess(func: (T) -> Unit): Result = when (this) {
is Success -> {
func(value)
this
}
is Failure -> this
}
public inline fun onFailure(func: (Throwable) -> Unit): Result = when (this) {
is Success -> this
is Failure -> {
func(throwable)
this
}
}
public inline fun combine(other: Result, func: (T, T) -> R): Result {
return when {
this is Success && other is Success -> Success(func(this.value, other.value))
this is Failure && other is Success -> Failure(this.throwable)
this is Success && other is Failure -> Failure(other.throwable)
this is Failure && other is Failure -> Failure(
CompositeException(
"${this.throwable.message}\n${other.throwable.message}",
arrayOf(this.throwable, other.throwable)
)
)
else -> throw IllegalStateException("this shouldn't happen")
}
}
public class Success(public val value: T) : Result() {
override fun equals(other: Any?): Boolean = when (other) {
is Success<*> -> value == other.value
else -> false
}
override fun hashCode(): Int = value?.hashCode() ?: 0
override fun toString(): String = "Success[$value]"
}
public class Failure(public val throwable: Throwable) : Result() {
override fun equals(other: Any?): Boolean = when (other) {
is Failure<*> -> throwable == other.throwable
else -> false
}
override fun hashCode(): Int = throwable.hashCode()
override fun toString(): String = "Failure[${throwable.message}]"
}
public companion object {
public inline fun tryCatch(func: () -> T): Result = try {
Success(func.invoke())
} catch (e: Throwable) {
Failure(e)
}
}
}
@OptIn(ExperimentalContracts::class)
public fun Result.isFailure(): Boolean {
contract {
returns(true) implies (this@isFailure is Result.Failure)
}
return this is Result.Failure
}
@OptIn(ExperimentalContracts::class)
public fun Result.isSuccess(): Boolean {
contract {
returns(true) implies (this@isSuccess is Result.Success)
}
return this is Result.Success
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy