-
Notifications
You must be signed in to change notification settings - Fork 8
/
Skie_SuspendHandler.kt
51 lines (41 loc) · 1.7 KB
/
Skie_SuspendHandler.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package co.touchlab.skie.runtime.coroutines.suspend
import co.touchlab.skie.runtime.coroutines.suspend.internal.CoroutineDispatcherWithDelegate
import co.touchlab.skie.runtime.coroutines.suspend.internal.toNSError
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlin.reflect.KClass
@Suppress("ClassName")
class Skie_SuspendHandler(
private val cancellationHandler: Skie_CancellationHandler,
dispatcherDelegate: Skie_DispatcherDelegate,
private val onResult: (Skie_SuspendResult) -> Unit,
) {
private val dispatcher = CoroutineDispatcherWithDelegate(dispatcherDelegate)
internal fun launch(checkedExceptions: Array<KClass<out Throwable>>, coroutine: suspend () -> Any?) {
CoroutineScope(dispatcher).launch {
cancellationHandler.setCancellationCallback {
cancel()
}
try {
val result = coroutine.invoke()
onResult(Skie_SuspendResult.Success(result))
} catch (_: CancellationException) {
onResult(Skie_SuspendResult.Canceled)
} catch (e: Throwable) {
if (e.isCheckedException(checkedExceptions)) {
throwSwiftException(e)
} else {
throw e
}
}
}
}
private fun Throwable.isCheckedException(checkedExceptions: Array<out KClass<out Throwable>>): Boolean =
checkedExceptions.any { it.isInstance(this) }
private fun throwSwiftException(e: Throwable) {
val error = e.toNSError()
onResult(Skie_SuspendResult.Error(error))
}
}