Skip to content

Commit

Permalink
Add mapCatching
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbull committed Mar 8, 2024
1 parent f208f5e commit 15fc1ff
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,29 @@ public inline infix fun <V, E, U> Result<V, E>.map(transform: (V) -> U): Result<
}
}

/**
* Maps this [Result<V, Throwable>][Result] to [Result<U, Throwable>][Result] by either applying
* the [transform] function to the [value][Ok.value] if this [Result] is [Ok], or returning this
* [Err].
*
* This function catches any [Throwable] exception thrown by [transform] function and encapsulates
* it as a failure.
*
* - Elm: [Result.map](http://package.elm-lang.org/packages/elm-lang/core/latest/Result#map)
* - Haskell: [Data.Bifunctor.first](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Bifunctor.html#v:first)
* - Rust: [Result.map](https://doc.rust-lang.org/std/result/enum.Result.html#method.map)
*/
public inline infix fun <V, U> Result<V, Throwable>.mapCatching(transform: (V) -> U): Result<U, Throwable> {
contract {
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
}

return when (this) {
is Ok -> runCatching { transform(value) }
is Err -> this
}
}

/**
* Maps this [Result<Result<V, E>, E>][Result] to [Result<V, E>][Result].
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,41 @@ class MapTest {
}
}

class MapCatching {

private object MapException : Throwable()

@Test
fun returnsTransformedValueIfOk() {
val value: Result<Int, Throwable> = Ok(10)

assertEquals(
expected = Ok(30),
actual = value.mapCatching { it + 20 },
)
}

@Test
fun returnsErrIfTransformationThrows() {
val value: Result<Int, Throwable> = Ok(10)

assertEquals(
expected = Err(MapException),
actual = value.mapCatching { throw MapException },
)
}

@Test
fun returnsErrorIfErr() {
val value: Result<Int, Throwable> = Err(MapException)

assertEquals(
expected = Err(MapException),
actual = value.mapCatching { "hello $it" },
)
}
}

class Flatten {

@Test
Expand Down

0 comments on commit 15fc1ff

Please sign in to comment.