Skip to content

Commit

Permalink
1.9.0: More plain Result features (#10)
Browse files Browse the repository at this point in the history
- add WasmJS target
- add WasmWasi target (not or KmmResult-test, as Kotest does not support WASI yet)
- Function Renames (old ones are still present, but deprecated)
- rename `wrapping` -> `catchingAs` but keep the old names as deprecated alternative
  - add `catchingUnwrappedAs`, which works just like `catchingAs` but on a `Result` rather than a `KmmResult` to avoid instantiation overhead
  • Loading branch information
JesusMcCloud authored Oct 28, 2024
1 parent 78acabc commit d4f7eeb
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 168 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build-jvm.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: Build JVM/JS/iOS/macOS/tvOS/MinGW/Linux
name: Build JVM/JS/iOS/macOS/tvOS/MinGW/wasmJS/wasmWasi/Linux
on: [push]
jobs:
build:
runs-on: ubuntu-latest
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,11 @@
- `result.shouldSucceed()` returning the contained value
- remove Arrow dependency and import arrow's list of Fatal exceptions directly into our code
- Introduce `Result.nonFatalOrThrow` to mimic KmmResult's non-fatal-only behaviour, but without the object instantiation overhead
- Introduce `carchingUnwrapped`, which mimics KmmResult's non-fatal-only behaviour, but without the object instantiation overhead
- Introduce `carchingUnwrapped`, which mimics KmmResult's non-fatal-only behaviour, but without the object instantiation overhead

## 1.9.0
- add WasmJS target
- add WasmWasi target (not for KmmResult-test, as Kotest does not support WASI yet)
- Function Renames (old ones are still present, but deprecated)
- rename `wrapping` -> `catchingAs` but keep the old names as deprecated alternative
- add `catchingUnwrappedAs`, which works just like `catchingAs` but on a `Result` rather than a `KmmResult` to avoid instantiation overhead
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ is *not* a value class (a sealed `Either` type also does not interop well with S

`KmmResult` comes to the rescue! → [Full documentation](https://a-sit-plus.github.io/KmmResult/).


## Using in your Projects

This library is available at maven central.
Expand Down Expand Up @@ -88,12 +87,11 @@ KmmResult comes with `catching`. This is a non-fatal-only-catching version of st
It re-throws any fatal exceptions, such as `OutOfMemoryError`. The underlying logic is borrowed from [Arrow's](https://arrow-kt.io)'s
[`nonFatalOrThrow`](https://apidocs.arrow-kt.io/arrow-core/arrow.core/non-fatal-or-throw.html).

The only downside of `catching` is that it incurs instatiation overhead, because it creates a `KmmResult` instance.
The only downside of `catching` is that it incurs instantiation overhead, because it creates a `KmmResult` instance.
Internally, though, only the behaviour is important, not Swift interop. Hence, you don't care for a `KmmResult` and you
certainly don't care for the cost of instantiating an object. Here, the `Result.nonFatalOrThrow()` extension shipped with KmmResult
comes to the rescue. It does exactly what the name suggest: It re-throws any fatal exception and leaved the `Result` object
untouched otherwise.

comes to the rescue. It does exactly what the name suggest: It re-throws any fatal exception and leaves the `Result` object
untouched otherwise. As a convenience shorthand, there's `catchingUnwrapped` which directly returns an stdlib `Result`.

Happy folding!

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ kotlin.mpp.enableCInteropCommonization=true
kotlin.mpp.stability.nowarn=true
kotlin.native.ignoreDisabledTargets=true

artifactVersion = 1.8.0
artifactVersion = 1.9.0
org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
15 changes: 9 additions & 6 deletions kmmresult-test/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import io.gitlab.arturbosch.detekt.Detekt
import org.gradle.kotlin.dsl.support.listFilesOrdered
import java.lang.management.ManagementFactory
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
import java.net.URI

plugins {
Expand Down Expand Up @@ -86,18 +85,22 @@ kotlin {
withJava() //for Java Interop tests
}

js(IR) {
browser { testTask { enabled = false } }
nodejs()
listOf(
js(IR).apply { browser { testTask { enabled = false } } },
@OptIn(ExperimentalWasmDsl::class)
wasmJs().apply { browser { testTask { enabled = false } } }
).forEach {
it.nodejs()
}

linuxX64()
linuxArm64()
mingwX64()

sourceSets {
commonMain.dependencies {
implementation(project(":kmmresult"))
api("io.kotest:kotest-assertions-core:5.9.1")
api("io.kotest:kotest-assertions-core:6.0.0.M1")
}
}

Expand Down
14 changes: 10 additions & 4 deletions kmmresult/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import io.gitlab.arturbosch.detekt.Detekt
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
import java.net.URI

plugins {
Expand Down Expand Up @@ -78,7 +79,6 @@ kotlin {
it.binaries.framework {
baseName = "KmmResult"
binaryOption("bundleId", "at.asitplus.KmmResult")
embedBitcode("bitcode")
xcf.add(this)
isStatic = true
}
Expand All @@ -96,9 +96,15 @@ kotlin {
withJava() //for Java Interop tests
}

js(IR) {
browser { testTask { enabled = false } }
nodejs()

listOf(
js(IR).apply { browser { testTask { enabled = false } } },
@OptIn(ExperimentalWasmDsl::class)
wasmJs().apply { browser { testTask { enabled = false } } },
@OptIn(ExperimentalWasmDsl::class)
wasmWasi()
).forEach {
it.nodejs()
}

linuxX64()
Expand Down
89 changes: 0 additions & 89 deletions kmmresult/src/commonMain/kotlin/at/asitplus/KmmResult.kt
Original file line number Diff line number Diff line change
Expand Up @@ -264,92 +264,3 @@ inline fun <R, T : R> KmmResult<T>.recoverCatching(block: (error: Throwable) ->
else -> catching { block(x) }
}
}

/**
* Non-fatal-only-catching version of stdlib's [runCatching], directly returning a [KmmResult] --
* Re-throws any fatal exceptions, such as `OutOfMemoryError`. Re-implements [Arrow](https://arrow-kt.io)'s
* [nonFatalOrThrow](https://apidocs.arrow-kt.io/arrow-core/arrow.core/non-fatal-or-throw.html)
* logic to avoid a dependency on Arrow for a single function.
*/
@Suppress("TooGenericExceptionCaught")
inline fun <T> catching(block: () -> T): KmmResult<T> {
contract {
// not EXACTLY_ONCE, because inside a try block!
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
}
return try {
KmmResult.success(block())
} catch (e: Throwable) {
KmmResult.failure(e)
}
}

/**
* Non-fatal-only-catching version of stdlib's [runCatching] (calling the specified function [block] with `this` value
* as its receiver), directly returning a [KmmResult] --
* Re-throws any fatal exceptions, such as `OutOfMemoryError`. Re-implements [Arrow](https://arrow-kt.io)'s
* [nonFatalOrThrow](https://apidocs.arrow-kt.io/arrow-core/arrow.core/non-fatal-or-throw.html)
* logic to avoid a dependency on Arrow for a single function.
*/
@Suppress("TooGenericExceptionCaught")
inline fun <T, R> T.catching(block: T.() -> R): KmmResult<R> {
contract {
// not EXACTLY_ONCE, because inside a try block!
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
}
return try {
KmmResult.success(block())
} catch (e: Throwable) {
KmmResult.failure(e)
}
}

/**
* Runs the specified function [block], returning a [KmmResult].
* Any non-fatal exception will be wrapped as the specified exception, unless it is already the specified type.
*
* Usage: `wrapping(asA = ::ThrowableType) { block }`.
*/
@Suppress("TooGenericExceptionCaught")
inline fun <reified E : Throwable, R> wrapping(asA: (String?, Throwable) -> E, block: () -> R): KmmResult<R> {
contract {
callsInPlace(asA, InvocationKind.AT_MOST_ONCE)
// not EXACTLY_ONCE, because inside a try block!
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
}
return try {
KmmResult.success(block())
} catch (e: Throwable) {
KmmResult.failure(
when (e.nonFatalOrThrow()) {
is E -> e
else -> asA(e.message, e)
}
)
}
}

/**
* Runs the specified function [block] with `this` as its receiver, returning a [KmmResult].
* Any non-fatal exception will be wrapped as the specified exception, unless it is already the specified type.
*
* Usage: `wrapping(asA = ::ThrowableType) { block }`.
*/
@Suppress("TooGenericExceptionCaught")
inline fun <reified E : Throwable, T, R> T.wrapping(asA: (String?, Throwable) -> E, block: T.() -> R): KmmResult<R> {
contract {
callsInPlace(asA, InvocationKind.AT_MOST_ONCE)
// not EXACTLY_ONCE, because inside a try block!
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
}
return try {
KmmResult.success(block())
} catch (e: Throwable) {
KmmResult.failure(
when (e.nonFatalOrThrow()) {
is E -> e
else -> asA(e.message, e)
}
)
}
}
37 changes: 0 additions & 37 deletions kmmresult/src/commonMain/kotlin/at/asitplus/NonFatal.kt

This file was deleted.

Loading

0 comments on commit d4f7eeb

Please sign in to comment.