Skip to content

Commit

Permalink
1.5.4
Browse files Browse the repository at this point in the history
Add transform functionality
  • Loading branch information
JesusMcCloud authored Nov 14, 2023
2 parents 5cef3f5 + c1a76e9 commit edeeb13
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 2 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@
- Kotlin 1.9.0

### 1.5.3
- Kotlin 1.9.10
- Kotlin 1.9.10

### 1.5.4
- Add `transform()` function to map results without nesting
- Add `mapCatching()`
- Implement `equals()` and `hashCode()`
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ kotlin.native.binary.freezing=disabled
kotlin.mpp.stability.nowarn=true
kotlin.native.ignoreDisabledTargets=true

artifactVersion = 1.5.3
artifactVersion = 1.5.4
32 changes: 32 additions & 0 deletions src/commonMain/kotlin/at/asitplus/KmmResult.kt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,25 @@ class KmmResult<T> private constructor(
inline fun <R> map(block: (T) -> R): KmmResult<R> =
getOrNull()?.let { success(block(it)) } ?: this as KmmResult<R>

/**
* Transforms this KmmResult into a KmmResult of different success type according to `block` and leaves the
* failure case untouched. Avoids nested KmmResults
*/
@Suppress("UNCHECKED_CAST")
inline fun <R> transform(block: (T) -> KmmResult<R>): KmmResult<R> =
getOrNull()?.let { block(it) } ?: this as KmmResult<R>

/**
* Returns the encapsulated result of the given [block] function applied to the encapsulated value
* if this instance represents [success][KmmResult.isSuccess] or the
* original encapsulated [Throwable] exception if it is [failure][KmmResult.isFailure].
*
* This function catches any [Throwable] exception thrown by [block] function and encapsulates it as a failure.
* See [map] for an alternative that rethrows exceptions from `transform` function.
*/
@Suppress("UNCHECKED_CAST")
inline fun <R> mapCatching(block: (T) -> R): KmmResult<R> = unwrap().mapCatching { block(it) }.wrap()

/**
* Transforms this KmmResult's failure-case according to `block` and leaves the success case untouched
* (type erasure FTW!)
Expand Down Expand Up @@ -134,6 +153,19 @@ class KmmResult<T> private constructor(
exName?.let { ")" }
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false

other as KmmResult<*>

return delegate == other.delegate
}

override fun hashCode(): Int {
return delegate.hashCode()
}

@OptIn(ExperimentalObjCRefinement::class)
companion object {
@HiddenFromObjC
Expand Down
12 changes: 12 additions & 0 deletions src/commonTest/kotlin/KmmResultTest.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package at.asitplus

import at.asitplus.KmmResult.Companion.success
import at.asitplus.KmmResult.Companion.wrap
import kotlin.test.*

class KmmResultTest {

@Test
fun testMap() {
assertEquals("1234", KmmResult.success(1234).map { it.toString() }.getOrThrow())
Expand All @@ -15,6 +17,16 @@ class KmmResultTest {
assertEquals(9, KmmResult.success(3).map { it * 3 }.getOrThrow())
}

@Test
fun testTransform() {
val intResult = success(1234)
val stringResult = success("1234")
assertEquals(stringResult, intResult.transform { success(it.toString()) })
val throwable = NullPointerException("Null")
val fail: KmmResult<Int> = KmmResult.failure(throwable)
assertEquals(fail, fail.transform { success( it * 3 ) })
}

@Test
fun testMapFailure() {
assertTrue(
Expand Down

0 comments on commit edeeb13

Please sign in to comment.