Add flatMap{Both,Either}
This commit is contained in:
parent
5d2c732ae7
commit
4e5cdeede7
@ -22,6 +22,151 @@ public inline infix fun <V, E, U> Result<V, E>.map(transform: (V) -> U): Result<
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<Result<V, E>, E>][Result] to [Result<V, E>][Result].
|
||||
*
|
||||
* - Rust: [Result.flatten](https://doc.rust-lang.org/std/result/enum.Result.html#method.flatten)
|
||||
*/
|
||||
public inline fun <V, E> Result<Result<V, E>, E>.flatten(): Result<V, E> {
|
||||
return when (this) {
|
||||
is Ok -> value
|
||||
is Err -> this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<V, E>][Result] to [Result<U, E>][Result] by either applying the [transform]
|
||||
* function if this [Result] is [Ok], or returning this [Err].
|
||||
*
|
||||
* This is functionally equivalent to [andThen].
|
||||
*
|
||||
* - Scala: [Either.flatMap](http://www.scala-lang.org/api/2.12.0/scala/util/Either.html#flatMap[AA>:A,Y](f:B=>scala.util.Either[AA,Y]):scala.util.Either[AA,Y])
|
||||
*/
|
||||
public inline infix fun <V, E, U> Result<V, E>.flatMap(transform: (V) -> Result<U, E>): Result<U, E> {
|
||||
contract {
|
||||
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return andThen(transform)
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<V, E>][Result] to [U] by applying either the [success] function if this
|
||||
* [Result] is [Ok], or the [failure] function if this [Result] is an [Err].
|
||||
*
|
||||
* Unlike [mapEither], [success] and [failure] must both return [U].
|
||||
*
|
||||
* - Elm: [Result.Extra.mapBoth](http://package.elm-lang.org/packages/elm-community/result-extra/2.2.0/Result-Extra#mapBoth)
|
||||
* - Haskell: [Data.Either.either](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:either)
|
||||
*/
|
||||
public inline fun <V, E, U> Result<V, E>.mapBoth(
|
||||
success: (V) -> U,
|
||||
failure: (E) -> U,
|
||||
): U {
|
||||
contract {
|
||||
callsInPlace(success, InvocationKind.AT_MOST_ONCE)
|
||||
callsInPlace(failure, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
is Ok -> success(value)
|
||||
is Err -> failure(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<V, E>][Result] to [U] by applying either the [success] function if this
|
||||
* [Result] is [Ok], or the [failure] function if this [Result] is an [Err].
|
||||
*
|
||||
* Unlike [mapEither], [success] and [failure] must both return [U].
|
||||
*
|
||||
* This is functionally equivalent to [mapBoth].
|
||||
*
|
||||
* - Elm: [Result.Extra.mapBoth](http://package.elm-lang.org/packages/elm-community/result-extra/2.2.0/Result-Extra#mapBoth)
|
||||
* - Haskell: [Data.Either.either](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:either)
|
||||
*/
|
||||
public inline fun <V, E, U> Result<V, E>.fold(
|
||||
success: (V) -> U,
|
||||
failure: (E) -> U,
|
||||
): U {
|
||||
contract {
|
||||
callsInPlace(success, InvocationKind.AT_MOST_ONCE)
|
||||
callsInPlace(failure, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return mapBoth(success, failure)
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<V, E>][Result] to [Result<U, E>][Result] by applying either the [success]
|
||||
* function if this [Result] is [Ok], or the [failure] function if this [Result] is an [Err].
|
||||
*
|
||||
* Unlike [mapEither], [success] and [failure] must both return [U].
|
||||
*
|
||||
* - Elm: [Result.Extra.mapBoth](http://package.elm-lang.org/packages/elm-community/result-extra/2.2.0/Result-Extra#mapBoth)
|
||||
* - Haskell: [Data.Either.either](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:either)
|
||||
*/
|
||||
public inline fun <V, E, U> Result<V, E>.flatMapBoth(
|
||||
success: (V) -> Result<U, E>,
|
||||
failure: (E) -> Result<U, E>,
|
||||
): Result<U, E> {
|
||||
contract {
|
||||
callsInPlace(success, InvocationKind.AT_MOST_ONCE)
|
||||
callsInPlace(failure, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
is Ok -> success(value)
|
||||
is Err -> failure(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<V, E>][Result] to [Result<U, F>][Result] by applying either the [success]
|
||||
* function if this [Result] is [Ok], or the [failure] function if this [Result] is an [Err].
|
||||
*
|
||||
* Unlike [mapBoth], [success] and [failure] may either return [U] or [F] respectively.
|
||||
*
|
||||
* - Haskell: [Data.Bifunctor.Bimap](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Bifunctor.html#v:bimap)
|
||||
*/
|
||||
public inline fun <V, E, U, F> Result<V, E>.mapEither(
|
||||
success: (V) -> U,
|
||||
failure: (E) -> F,
|
||||
): Result<U, F> {
|
||||
contract {
|
||||
callsInPlace(success, InvocationKind.AT_MOST_ONCE)
|
||||
callsInPlace(failure, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
is Ok -> Ok(success(value))
|
||||
is Err -> Err(failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<V, E>][Result] to [Result<U, F>][Result] by applying either the [success]
|
||||
* function if this [Result] is [Ok], or the [failure] function if this [Result] is an [Err].
|
||||
*
|
||||
* Unlike [mapBoth], [success] and [failure] may either return [U] or [F] respectively.
|
||||
*
|
||||
* - Haskell: [Data.Bifunctor.Bimap](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Bifunctor.html#v:bimap)
|
||||
*/
|
||||
public inline fun <V, E, U, F> Result<V, E>.flatMapEither(
|
||||
success: (V) -> Result<U, F>,
|
||||
failure: (E) -> Result<U, F>,
|
||||
): Result<U, F> {
|
||||
contract {
|
||||
callsInPlace(success, InvocationKind.AT_MOST_ONCE)
|
||||
callsInPlace(failure, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
is Ok -> success(value)
|
||||
is Err -> failure(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<V, E>][Result] to [Result<V, F>][Result] by either applying the [transform]
|
||||
* function to the [error][Err.error] if this [Result] is [Err], or returning this [Ok].
|
||||
@ -94,88 +239,6 @@ public inline infix fun <V, E, U> Result<Iterable<V>, E>.mapAll(transform: (V) -
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<V, E>][Result] to [U] by applying either the [success] function if this
|
||||
* [Result] is [Ok], or the [failure] function if this [Result] is an [Err]. Both of these
|
||||
* functions must return the same type ([U]).
|
||||
*
|
||||
* - Elm: [Result.Extra.mapBoth](http://package.elm-lang.org/packages/elm-community/result-extra/2.2.0/Result-Extra#mapBoth)
|
||||
* - Haskell: [Data.Either.either](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:either)
|
||||
*/
|
||||
public inline fun <V, E, U> Result<V, E>.mapBoth(success: (V) -> U, failure: (E) -> U): U {
|
||||
contract {
|
||||
callsInPlace(success, InvocationKind.AT_MOST_ONCE)
|
||||
callsInPlace(failure, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
is Ok -> success(value)
|
||||
is Err -> failure(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<V, E>][Result] to [U] by applying either the [success] function if this
|
||||
* [Result] is [Ok], or the [failure] function if this [Result] is an [Err]. Both of these
|
||||
* functions must return the same type ([U]).
|
||||
*
|
||||
* This is functionally equivalent to [mapBoth].
|
||||
*
|
||||
* - Elm: [Result.Extra.mapBoth](http://package.elm-lang.org/packages/elm-community/result-extra/2.2.0/Result-Extra#mapBoth)
|
||||
* - Haskell: [Data.Either.either](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Either.html#v:either)
|
||||
*/
|
||||
public inline fun <V, E, U> Result<V, E>.fold(success: (V) -> U, failure: (E) -> U): U {
|
||||
contract {
|
||||
callsInPlace(success, InvocationKind.AT_MOST_ONCE)
|
||||
callsInPlace(failure, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return mapBoth(success, failure)
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<V, E>][Result] to [Result<U, F>][Result] by applying either the [success]
|
||||
* function if this [Result] is [Ok], or the [failure] function if this [Result] is an [Err].
|
||||
*
|
||||
* - Haskell: [Data.Bifunctor.Bimap](https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Bifunctor.html#v:bimap)
|
||||
*/
|
||||
public inline fun <V, E, U, F> Result<V, E>.mapEither(success: (V) -> U, failure: (E) -> F): Result<U, F> {
|
||||
contract {
|
||||
callsInPlace(success, InvocationKind.AT_MOST_ONCE)
|
||||
callsInPlace(failure, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return when (this) {
|
||||
is Ok -> Ok(success(value))
|
||||
is Err -> Err(failure(error))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<V, E>][Result] to [Result<U, E>][Result] by either applying the [transform]
|
||||
* function if this [Result] is [Ok], or returning this [Err].
|
||||
*
|
||||
* This is functionally equivalent to [andThen].
|
||||
*
|
||||
* - Scala: [Either.flatMap](http://www.scala-lang.org/api/2.12.0/scala/util/Either.html#flatMap[AA>:A,Y](f:B=>scala.util.Either[AA,Y]):scala.util.Either[AA,Y])
|
||||
*/
|
||||
public inline infix fun <V, E, U> Result<V, E>.flatMap(transform: (V) -> Result<U, E>): Result<U, E> {
|
||||
contract {
|
||||
callsInPlace(transform, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
|
||||
return andThen(transform)
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps this [Result<Result<V, E>, E>][Result] to [Result<V, E>][Result].
|
||||
*
|
||||
* - Rust: [Result.flatten](https://doc.rust-lang.org/std/result/enum.Result.html#method.flatten)
|
||||
*/
|
||||
public inline fun <V, E> Result<Result<V, E>, E>.flatten(): Result<V, E> {
|
||||
return andThen { it }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the [transformation][transform] of the [value][Ok.value] if this [Result] is [Ok]
|
||||
* and satisfies the given [predicate], otherwise this [Result].
|
||||
@ -194,6 +257,7 @@ public inline fun <V, E> Result<V, E>.toErrorIf(predicate: (V) -> Boolean, trans
|
||||
} else {
|
||||
this
|
||||
}
|
||||
|
||||
is Err -> this
|
||||
}
|
||||
}
|
||||
@ -215,6 +279,7 @@ public inline fun <V, E> Result<V?, E>.toErrorIfNull(error: () -> E): Result<V,
|
||||
} else {
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
is Err -> this
|
||||
}
|
||||
}
|
||||
@ -237,6 +302,7 @@ public inline fun <V, E> Result<V, E>.toErrorUnless(predicate: (V) -> Boolean, t
|
||||
} else {
|
||||
this
|
||||
}
|
||||
|
||||
is Err -> this
|
||||
}
|
||||
}
|
||||
@ -258,6 +324,7 @@ public inline fun <V, E> Result<V, E>.toErrorUnlessNull(error: () -> E): Result<
|
||||
} else {
|
||||
Err(error())
|
||||
}
|
||||
|
||||
is Err -> Err(error())
|
||||
}
|
||||
}
|
||||
|
@ -3,175 +3,41 @@ package com.github.michaelbull.result
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNull
|
||||
import kotlin.test.assertSame
|
||||
|
||||
class MapTest {
|
||||
private sealed class MapErr(val reason: String) {
|
||||
object HelloError : MapErr("hello")
|
||||
object WorldError : MapErr("world")
|
||||
class CustomError(reason: String) : MapErr(reason)
|
||||
private sealed interface MapErr {
|
||||
val reason: String
|
||||
|
||||
data object HelloError : MapErr {
|
||||
override val reason = "hello"
|
||||
}
|
||||
|
||||
data object WorldError : MapErr {
|
||||
override val reason = "world"
|
||||
}
|
||||
|
||||
data class CustomError(override val reason: String) : MapErr
|
||||
}
|
||||
|
||||
class Map {
|
||||
|
||||
@Test
|
||||
fun returnsTransformedValueIfOk() {
|
||||
assertEquals(
|
||||
expected = 30,
|
||||
actual = Ok(10).map { it + 20 }.get()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Suppress("UNREACHABLE_CODE")
|
||||
fun returnsErrorIfErr() {
|
||||
val result = Err(MapErr.HelloError).map { "hello $it" }
|
||||
|
||||
result as Err
|
||||
|
||||
assertSame(
|
||||
expected = MapErr.HelloError,
|
||||
actual = result.error
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MapError {
|
||||
@Test
|
||||
fun returnsValueIfOk() {
|
||||
val value = Ok(55).map { it + 15 }.mapError { MapErr.WorldError }.get()
|
||||
val value: Result<Int, MapErr> = Ok(10)
|
||||
|
||||
assertEquals(
|
||||
expected = 70,
|
||||
actual = value
|
||||
expected = Ok(30),
|
||||
actual = value.map { it + 20 }
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsErrorIfErr() {
|
||||
val result: Result<String, MapErr> = Ok("let")
|
||||
.map { "$it me" }
|
||||
.andThen {
|
||||
when (it) {
|
||||
"let me" -> Err(MapErr.CustomError("$it $it"))
|
||||
else -> Ok("$it get")
|
||||
}
|
||||
}
|
||||
.mapError { MapErr.CustomError("${it.reason} get what i want") }
|
||||
|
||||
result as Err
|
||||
val value: Result<Int, MapErr> = Err(MapErr.HelloError)
|
||||
|
||||
assertEquals(
|
||||
expected = "let me let me get what i want",
|
||||
actual = result.error.reason
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MapOr {
|
||||
@Test
|
||||
fun returnsTransformedValueIfOk() {
|
||||
val value = Ok("foo").mapOr(42, String::length)
|
||||
|
||||
assertEquals(
|
||||
expected = 3,
|
||||
actual = value
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsDefaultValueIfErr() {
|
||||
val value = Err("bar").mapOr(42, String::length)
|
||||
|
||||
assertEquals(
|
||||
expected = 42,
|
||||
actual = value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MapOrElse {
|
||||
private val k = 21
|
||||
|
||||
@Test
|
||||
fun returnsTransformedValueIfOk() {
|
||||
val value = Ok("foo").mapOrElse({ k * 2 }, String::length)
|
||||
|
||||
assertEquals(
|
||||
expected = 3,
|
||||
actual = value
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsDefaultValueIfErr() {
|
||||
val value = Err("bar").mapOrElse({ k * 2 }, String::length)
|
||||
|
||||
assertEquals(
|
||||
expected = 42,
|
||||
actual = value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MapBoth {
|
||||
@Test
|
||||
@Suppress("UNREACHABLE_CODE")
|
||||
fun returnsTransformedValueIfOk() {
|
||||
val value = Ok("there is").mapBoth(
|
||||
success = { "$it a light" },
|
||||
failure = { "$it that never" }
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = "there is a light",
|
||||
actual = value
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Suppress("UNREACHABLE_CODE")
|
||||
fun returnsTransformedErrorIfErr() {
|
||||
val error = Err(MapErr.CustomError("this")).mapBoth(
|
||||
success = { "$it charming" },
|
||||
failure = { "${it.reason} man" }
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = "this man",
|
||||
actual = error
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MapEither {
|
||||
@Test
|
||||
@Suppress("UNREACHABLE_CODE")
|
||||
fun returnsTransformedValueIfOk() {
|
||||
val result = Ok(500).mapEither(
|
||||
success = { it + 500 },
|
||||
failure = { MapErr.CustomError("$it") }
|
||||
)
|
||||
|
||||
result as Ok
|
||||
|
||||
assertEquals(
|
||||
expected = 1000,
|
||||
actual = result.value
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsTransformedErrorIfErr() {
|
||||
val result = Err("the reckless").mapEither(
|
||||
success = { "the wild youth" },
|
||||
failure = { MapErr.CustomError("the truth") }
|
||||
)
|
||||
|
||||
result as Err
|
||||
|
||||
assertEquals(
|
||||
expected = "the truth",
|
||||
actual = result.error.reason
|
||||
expected = Err(MapErr.HelloError),
|
||||
actual = value.map { "hello $it" }
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -224,6 +90,208 @@ class MapTest {
|
||||
}
|
||||
}
|
||||
|
||||
class MapError {
|
||||
|
||||
@Test
|
||||
fun returnsValueIfOk() {
|
||||
val value: Result<Int, MapErr> = Ok(70)
|
||||
|
||||
assertEquals(
|
||||
expected = Ok(70),
|
||||
actual = value.mapError { MapErr.WorldError }
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsErrorIfErr() {
|
||||
val value: Result<Int, MapErr> = Err(MapErr.HelloError)
|
||||
|
||||
assertEquals(
|
||||
expected = Err(MapErr.WorldError),
|
||||
actual = value.mapError { MapErr.WorldError }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MapOr {
|
||||
|
||||
@Test
|
||||
fun returnsTransformedValueIfOk() {
|
||||
val value: Result<String, String> = Ok("foo")
|
||||
|
||||
assertEquals(
|
||||
expected = 3,
|
||||
actual = value.mapOr(42, String::length)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsDefaultValueIfErr() {
|
||||
val value: Result<String, String> = Err("foo")
|
||||
|
||||
assertEquals(
|
||||
expected = 42,
|
||||
actual = value.mapOr(42, String::length)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MapOrElse {
|
||||
private val k = 21
|
||||
|
||||
@Test
|
||||
fun returnsTransformedValueIfOk() {
|
||||
val value: Result<String, String> = Ok("foo")
|
||||
|
||||
assertEquals(
|
||||
expected = 3,
|
||||
actual = value.mapOrElse({ k * 2 }, String::length)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsDefaultValueIfErr() {
|
||||
val value: Result<String, String> = Err("foo")
|
||||
|
||||
assertEquals(
|
||||
expected = 42,
|
||||
actual = value.mapOrElse({ k * 2 }, String::length)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MapBoth {
|
||||
|
||||
@Test
|
||||
fun returnsTransformedValueIfOk() {
|
||||
val value: Result<Int, Long> = Ok(50)
|
||||
|
||||
val result: String = value.mapBoth(
|
||||
success = { "good $it" },
|
||||
failure = { "bad $it" }
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = "good 50",
|
||||
actual = result
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsTransformedErrorIfErr() {
|
||||
val value: Result<Int, Long> = Err(20)
|
||||
|
||||
val result: String = value.mapBoth(
|
||||
success = { "good $it" },
|
||||
failure = { "bad $it" }
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = "bad 20",
|
||||
actual = result
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class FlatMapBoth {
|
||||
|
||||
@Test
|
||||
fun returnsTransformedValueIfOk() {
|
||||
val value: Result<Int, Long> = Ok(50)
|
||||
|
||||
val result: Result<String, Long> = value.flatMapBoth(
|
||||
success = { Ok("good $it") },
|
||||
failure = { Err(100L) }
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = Ok("good 50"),
|
||||
actual = result
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsTransformedErrorIfErr() {
|
||||
val result: Result<Int, Long> = Err(25L)
|
||||
|
||||
val value: Result<String, Long> = result.flatMapBoth(
|
||||
success = { Ok("good $it") },
|
||||
failure = { Err(100L) }
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = Err(100L),
|
||||
actual = value
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class MapEither {
|
||||
|
||||
@Test
|
||||
fun returnsTransformedValueIfOk() {
|
||||
val value: Result<Int, MapErr.HelloError> = Ok(500)
|
||||
|
||||
val result: Result<Long, MapErr.CustomError> = value.mapEither(
|
||||
success = { it + 500L },
|
||||
failure = { MapErr.CustomError("$it") }
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = Ok(1000L),
|
||||
actual = result
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsTransformedErrorIfErr() {
|
||||
val value: Result<Int, MapErr.HelloError> = Err(MapErr.HelloError)
|
||||
|
||||
val result: Result<Long, MapErr.CustomError> = value.mapEither(
|
||||
success = { it + 500L },
|
||||
failure = { MapErr.CustomError("bad") }
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = Err(MapErr.CustomError("bad")),
|
||||
actual = result
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class FlatMapEither {
|
||||
|
||||
@Test
|
||||
fun returnsTransformedValueIfOk() {
|
||||
val value: Result<Int, MapErr.HelloError> = Ok(500)
|
||||
|
||||
val result: Result<Long, MapErr.CustomError> = value.flatMapEither(
|
||||
success = { Ok(it + 500L) },
|
||||
failure = { Err(MapErr.CustomError("$it")) }
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = Ok(1000L),
|
||||
actual = result
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returnsTransformedErrorIfErr() {
|
||||
val value: Result<Int, MapErr.HelloError> = Err(MapErr.HelloError)
|
||||
|
||||
val result: Result<Long, MapErr.CustomError> = value.flatMapEither(
|
||||
success = { Ok(it + 500L) },
|
||||
failure = { Err(MapErr.CustomError("bad")) }
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
expected = Err(MapErr.CustomError("bad")),
|
||||
actual = result
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class ToErrorIfNull {
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user