package it.vfsfitvnm.youtubemusic sealed class Outcome { val valueOrNull: T? get() = when (this) { is Success -> value is Recovered -> value else -> null } fun recoverWith(value: @UnsafeVariance T): Outcome { return when (this) { is Error -> Recovered(value, this) else -> this } } inline fun map(block: (T) -> R): Outcome { return when (this) { is Success -> Success(block(value)) is Recovered -> Success(block(value)) is Initial -> this is Loading -> this is Error -> this } } inline fun flatMap(block: (T) -> Outcome): Outcome { return when (this) { is Success -> block(value) is Recovered -> block(value) is Initial -> this is Loading -> this is Error -> this } } object Initial : Outcome() object Loading : Outcome() sealed class Error : Outcome() { object Network : Error() class Unhandled(val throwable: Throwable) : Error() } class Recovered(val value: T, val error: Error) : Outcome() class Success(val value: T) : Outcome() } fun Outcome?.toNotNull(): Outcome { return when (this) { null -> Outcome.Success(null) else -> this } } fun Outcome.toNullable(): Outcome? { return valueOrNull?.let { Outcome.Success(it) } } val Outcome<*>.isEvaluable: Boolean get() = this !is Outcome.Success && this !is Outcome.Loading