Add mapping function for transformations with ResultsWithDiagnostics

also improve chaining helpers
This commit is contained in:
Ilya Chernikov
2019-01-08 12:18:39 +01:00
parent 01f2a21192
commit 7bb4233e17
@@ -60,18 +60,41 @@ sealed class ResultWithDiagnostics<out R> {
* If receiver is success - executes [body] and merge diagnostic reports
* otherwise returns the failure as is
*/
suspend fun <R1, R2> ResultWithDiagnostics<R1>.onSuccess(body: suspend (R1) -> ResultWithDiagnostics<R2>): ResultWithDiagnostics<R2> =
inline fun <R1, R2> ResultWithDiagnostics<R1>.onSuccess(body: (R1) -> ResultWithDiagnostics<R2>): ResultWithDiagnostics<R2> =
when (this) {
is ResultWithDiagnostics.Success -> this.reports + body(this.value)
is ResultWithDiagnostics.Failure -> this
}
/**
* maps transformation ([body]) over iterable merging diagnostics
* return failure with merged diagnostics after first failed transformation
* and success with merged diagnostics and list of results if all transformations succeeded
*/
inline fun<T, R> Iterable<T>.mapSuccess(body: (T) -> ResultWithDiagnostics<R>): ResultWithDiagnostics<List<R>> {
val reports = ArrayList<ScriptDiagnostic>()
val results = ArrayList<R>()
for (it in this) {
val result = body(it)
reports.addAll(result.reports)
when (result) {
is ResultWithDiagnostics.Success -> {
results.add(result.value)
}
else -> {
return ResultWithDiagnostics.Failure(reports)
}
}
}
return results.asSuccess(reports)
}
/**
* Chains actions on failure:
* If receiver is failure - executed [body]
* otherwise returns the receiver as is
*/
suspend fun <R> ResultWithDiagnostics<R>.onFailure(body: suspend (ResultWithDiagnostics<R>) -> Unit): ResultWithDiagnostics<R> {
inline fun <R> ResultWithDiagnostics<R>.onFailure(body: (ResultWithDiagnostics<R>) -> Unit): ResultWithDiagnostics<R> {
if (this is ResultWithDiagnostics.Failure) {
body(this)
}