diff --git a/CHANGELOG.md b/CHANGELOG.md index a05cb100c8e..f5e3fa4d824 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.5.3 + +* `Versions`: + * `Kotlin`: `1.5.0` -> `1.5.10` +* `Coroutines`: + * Extensions `doInUI` and `doInDefault` were replaced in common and available on any supported platform + * Extension `doInIO` replaced into `jvm` and available on any `JVM` platform + * Old extension `safelyWithouException` without `onException` has been replaced by its copy with `onException` and + default value + * New value `defaultSafelyWithoutExceptionHandlerWithNull` which is used in all `*WithoutExceptions` by default + * Analogs of `launch` and `async` for `safely` and `safelyWithoutExceptions` were added + * Analogs of `runCatching` for `safely` and `safelyWithoutExceptions` were added + ## 0.5.2 * `Ktor`: diff --git a/coroutines/build.gradle b/coroutines/build.gradle index 1db1b17ee79..840c8f52822 100644 --- a/coroutines/build.gradle +++ b/coroutines/build.gradle @@ -19,4 +19,4 @@ kotlin { } } } -} \ No newline at end of file +} diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/DoInContext.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/DoInContext.kt new file mode 100644 index 00000000000..d1587c784a1 --- /dev/null +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/DoInContext.kt @@ -0,0 +1,23 @@ +package dev.inmo.micro_utils.coroutines + +import kotlinx.coroutines.* +import kotlin.coroutines.CoroutineContext + +inline val UI + get() = Dispatchers.Main +inline val Default + get() = Dispatchers.Default + +suspend inline fun doIn(context: CoroutineContext, noinline block: suspend CoroutineScope.() -> T) = withContext( + context, + block +) + +suspend inline fun doInUI(noinline block: suspend CoroutineScope.() -> T) = doIn( + UI, + block +) +suspend inline fun doInDefault(noinline block: suspend CoroutineScope.() -> T) = doIn( + Default, + block +) diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/HandleSafely.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/HandleSafely.kt index d0bad07fc90..f84e6cdb8e1 100644 --- a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/HandleSafely.kt +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/HandleSafely.kt @@ -86,6 +86,9 @@ suspend fun safelyWithContextExceptionHandler( * * [CoroutineContext.get] with [SafelyExceptionHandlerKey] as key * * [defaultSafelyExceptionHandler] * + * Remember, that [ExceptionHandler] from [CoroutineContext.get] will be used anyway if it is available. After it will + * be called [onException] + * * @param [onException] Will be called when happen exception inside of [block]. By default will throw exception - this * exception will be available for catching * @@ -105,24 +108,38 @@ suspend inline fun safely( } } +suspend inline fun runCatchingSafely( + noinline onException: ExceptionHandler = defaultSafelyExceptionHandler, + noinline block: suspend CoroutineScope.() -> T +): Result = runCatching { + safely(onException, block) +} + +/** + * Use this handler in cases you wish to include handling of exceptions by [defaultSafelyWithoutExceptionHandler] and + * returning null at one time + * + * @see safelyWithoutExceptions + * @see launchSafelyWithoutExceptions + * @see asyncSafelyWithoutExceptions + */ +val defaultSafelyWithoutExceptionHandlerWithNull: ExceptionHandler = { + defaultSafelyWithoutExceptionHandler.invoke(it) + null +} + /** * Shortcut for [safely] with exception handler, that as expected must return null in case of impossible creating of - * result from exception (instead of throwing it) + * result from exception (instead of throwing it, by default always returns null) */ suspend inline fun safelyWithoutExceptions( - noinline onException: ExceptionHandler, + noinline onException: ExceptionHandler = defaultSafelyWithoutExceptionHandlerWithNull, noinline block: suspend CoroutineScope.() -> T ): T? = safely(onException, block) -/** - * Shortcut for [safely] without exception handler (instead of this you will always receive null as a result) - */ -suspend inline fun safelyWithoutExceptions( +suspend inline fun runCatchingSafelyWithoutExceptions( + noinline onException: ExceptionHandler = defaultSafelyWithoutExceptionHandlerWithNull, noinline block: suspend CoroutineScope.() -> T -): T? = safelyWithoutExceptions( - { - defaultSafelyWithoutExceptionHandler.invoke(it) - null - }, - block -) +): Result = runCatching { + safelyWithoutExceptions(onException, block) +} diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSafely.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSafely.kt new file mode 100644 index 00000000000..ff4850d5463 --- /dev/null +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSafely.kt @@ -0,0 +1,41 @@ +package dev.inmo.micro_utils.coroutines + +import kotlinx.coroutines.* +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext + +inline fun CoroutineScope.launchSafely( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + noinline onException: ExceptionHandler = defaultSafelyExceptionHandler, + noinline block: suspend CoroutineScope.() -> Unit +) = launch(context, start) { + safely(onException, block) +} + +inline fun CoroutineScope.launchSafelyWithoutExceptions( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + noinline onException: ExceptionHandler = defaultSafelyWithoutExceptionHandlerWithNull, + noinline block: suspend CoroutineScope.() -> Unit +) = launch(context, start) { + safelyWithoutExceptions(onException, block) +} + +inline fun CoroutineScope.asyncSafely( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + noinline onException: ExceptionHandler = defaultSafelyExceptionHandler, + noinline block: suspend CoroutineScope.() -> T +) = async(context, start) { + safely(onException, block) +} + +inline fun CoroutineScope.asyncSafelyWithoutExceptions( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + noinline onException: ExceptionHandler = defaultSafelyWithoutExceptionHandlerWithNull, + noinline block: suspend CoroutineScope.() -> T +) = async(context, start) { + safelyWithoutExceptions(onException, block) +} diff --git a/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/DoInIO.kt b/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/DoInIO.kt new file mode 100644 index 00000000000..fc5f79a7b06 --- /dev/null +++ b/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/DoInIO.kt @@ -0,0 +1,11 @@ +package dev.inmo.micro_utils.coroutines + +import kotlinx.coroutines.* + +val IO + get() = Dispatchers.IO + +suspend inline fun doInIO(noinline block: suspend CoroutineScope.() -> T) = doIn( + IO, + block +) diff --git a/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/DoWithFirstTests.kt b/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/DoWithFirstTests.kt index 22e611770ac..4d9e318824c 100644 --- a/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/DoWithFirstTests.kt +++ b/coroutines/src/jvmTest/kotlin/dev/inmo/micro_utils/coroutines/DoWithFirstTests.kt @@ -1,9 +1,8 @@ package dev.inmo.micro_utils.coroutines -import dev.inmo.micro_utils.coroutines.asDeferred -import dev.inmo.micro_utils.coroutines.launchSynchronously import kotlinx.coroutines.* -import kotlin.test.* +import kotlin.test.Test +import kotlin.test.assertEquals class DoWithFirstTests { @Test diff --git a/coroutines/src/main/kotlin/dev/inmo/micro_utils/coroutines/DoInUI.kt b/coroutines/src/main/kotlin/dev/inmo/micro_utils/coroutines/DoInUI.kt deleted file mode 100644 index ab23e3f87d7..00000000000 --- a/coroutines/src/main/kotlin/dev/inmo/micro_utils/coroutines/DoInUI.kt +++ /dev/null @@ -1,18 +0,0 @@ -package dev.inmo.micro_utils.coroutines - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext - -suspend inline fun doInUI(noinline block: suspend CoroutineScope.() -> T) = withContext( - Dispatchers.Main, - block -) -suspend inline fun doInDefault(noinline block: suspend CoroutineScope.() -> T) = withContext( - Dispatchers.Default, - block -) -suspend inline fun doInIO(noinline block: suspend CoroutineScope.() -> T) = withContext( - Dispatchers.IO, - block -) diff --git a/gradle.properties b/gradle.properties index 423a73fbded..2a97f11ba4e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ android.useAndroidX=true android.enableJetifier=true org.gradle.jvmargs=-Xmx2g -kotlin_version=1.5.0 +kotlin_version=1.5.10 kotlin_coroutines_version=1.5.0 kotlin_serialisation_core_version=1.2.1 kotlin_exposed_version=0.31.1 @@ -45,5 +45,5 @@ dokka_version=1.4.32 # Project data group=dev.inmo -version=0.5.2 -android_code_version=43 +version=0.5.3 +android_code_version=44