commonMain.arrow.ProgressiveOutcomeDsl.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of state Show documentation
Show all versions of state Show documentation
Progress-aware failure states
The newest version!
package opensavvy.state.arrow
import arrow.core.raise.Raise
import arrow.core.raise.RaiseDSL
import arrow.core.raise.recover
import opensavvy.progress.Progress
import opensavvy.progress.done
import opensavvy.state.ExperimentalProgressiveRaiseApi
import opensavvy.state.outcome.Outcome
import opensavvy.state.progressive.ProgressiveOutcome
import opensavvy.state.progressive.successfulWithProgress
import opensavvy.state.progressive.upcast
import opensavvy.state.progressive.withProgress
import kotlin.js.JsName
import kotlin.jvm.JvmInline
@JvmInline
@RaiseDSL
@ExperimentalProgressiveRaiseApi
value class ProgressiveOutcomeDsl(private val raise: Raise>) : Raise {
override fun raise(r: Failure): Nothing =
raise(r, done())
@RaiseDSL
@JsName("raiseUnsuccessful")
fun raise(failure: ProgressiveOutcome.Unsuccessful): Nothing =
raise.raise(failure)
@RaiseDSL
@JsName("raiseWithProgress")
fun raise(failure: Failure, progress: Progress = done()): Nothing =
raise(ProgressiveOutcome.Failure(failure, progress))
@RaiseDSL
fun Outcome.bind(progress: Progress = done()) =
this.withProgress(progress).bind()
@RaiseDSL
fun ProgressiveOutcome.bind(): T = when (this) {
is ProgressiveOutcome.Success -> value
is ProgressiveOutcome.Unsuccessful<*> -> {
@Suppress("UNCHECKED_CAST") // safe because it is guaranteed by the type bind on the receiver
raise.raise(this as ProgressiveOutcome.Unsuccessful)
}
}
}
/**
* Arrow-style DSL to execute a [Raise]-based computation to generate a [ProgressiveOutcome].
*
* **Warning:** the current implementation **does not** capture progress events fired during [block].
*/
@ExperimentalProgressiveRaiseApi
@RaiseDSL
inline fun progressive(block: ProgressiveOutcomeDsl.() -> Value): ProgressiveOutcome =
recover(
block = {
block(ProgressiveOutcomeDsl(this))
.successfulWithProgress(done())
},
recover = { it.upcast() },
)