From f301a7811d2e604dc37511a73ec22e555cfd7ec3 Mon Sep 17 00:00:00 2001 From: Lucas Riedhammer Date: Tue, 23 Feb 2021 14:03:12 +0100 Subject: [PATCH 1/7] add isSuccess, isFailure and getOrElse function --- README.md | 1 + .../kotlin/net/grandcentrix/either/Either.kt | 22 ++++++++++++ .../net/grandcentrix/either/EitherTest.kt | 36 ++++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fcfca3d..aaee153 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ successOrNull // property returning the success value if Success or null if Fail failureOrNull // property returning the failure value if Failure or null if Success onSuccess {} // executes given code block as side effect if Success and returns passed Either value unchanged onFailure {} // executes given code block as side effect if Failure and returns passed Either value unchanged +getOrElse {} // returns the encapsulated value if success or the result of the given code block Either.catch {} // executes the given code and returns its encapsulated result if invocation was successful and catching any exception that was thrown as a failure ``` diff --git a/either/src/main/kotlin/net/grandcentrix/either/Either.kt b/either/src/main/kotlin/net/grandcentrix/either/Either.kt index 8f39a1b..a7f4d03 100644 --- a/either/src/main/kotlin/net/grandcentrix/either/Either.kt +++ b/either/src/main/kotlin/net/grandcentrix/either/Either.kt @@ -69,6 +69,18 @@ sealed class Either { if (it is Failure) block(it.failure) } + /** + * Returns `true` if this instance represents a successful outcome. + * In this case [isFailure] returns `false`. + */ + val isSuccess: Boolean get() = this is Success + + /** + * Returns `true` if this instance represents a failed outcome. + * In this case [isSuccess] returns `false`. + */ + val isFailure: Boolean get() = this is Failure + companion object { /** @@ -143,6 +155,16 @@ inline fun Either.map(f: (S1) -> S2): Either = inline fun Either.mapFailure(f: (F1) -> F2): Either = fold({ Failure(f(it)) }, { Success(it) }) +/** + * Returns the encapsulated value if this instance represents [success][Either.isSuccess] or the + * result of [onFailure] function for the encapsulated [Failure] if it is [failure][Either.isFailure]. + * + * This function is a shorthand for `fold(onSuccess = { it }, onFailure = onFailure)` (see [fold]). + */ +inline fun Either.getOrElse(onFailure: (failure: F) -> S): S { + return fold(succeeded = { it }, failed = onFailure) +} + /** * Return the [Success] value of the [Either] if exist. If no success value exist it will return null. */ diff --git a/either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt b/either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt index a4af663..d34416d 100644 --- a/either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt +++ b/either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt @@ -1,7 +1,7 @@ package net.grandcentrix.either import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.* import org.junit.jupiter.api.Test import org.junit.jupiter.api.fail @@ -184,4 +184,38 @@ class EitherTest { val result = Either.catch { throw exception } assertThat(result).isEqualTo(Failure(exception)) } + + @Test + fun `when isSuccess on success return false`() { + assertTrue(Success("success result").isSuccess) + } + + @Test + fun `when isSuccess on failure return false`() { + assertFalse(Failure("failure result").isSuccess) + } + + @Test + fun `when isFailure on success should return false`() { + assertFalse(Success("success result").isFailure) + } + + @Test + fun `when isFailure on failure should return true`() { + assertTrue(Failure("failure result").isFailure) + } + + @Test + fun `when getOrElse with no failure should return success`() { + val either: Either = Success("success") + val result = either.getOrElse { "else" } + assertThat(result).isEqualTo("success") + } + + @Test + fun `when getOrElse with failure should return else block`() { + val either: Either = Failure("failure result") + val result = either.getOrElse { "else" } + assertThat(result).isEqualTo("else") + } } \ No newline at end of file From 52e7561b2a3a0e7662f5a8c35034b03df19302f4 Mon Sep 17 00:00:00 2001 From: Lucas Riedhammer Date: Tue, 23 Feb 2021 14:03:40 +0100 Subject: [PATCH 2/7] bump version --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9c46286..66c4b65 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ buildscript { allprojects { group = "net.grandcentrix.either" - version = "1.6" + version = "1.7" } } From 8a8f20c0b720f19e2600cb8629de2512c321083d Mon Sep 17 00:00:00 2001 From: Lucas Riedhammer Date: Wed, 24 Feb 2021 11:22:53 +0100 Subject: [PATCH 3/7] use expression body --- either/src/main/kotlin/net/grandcentrix/either/Either.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/either/src/main/kotlin/net/grandcentrix/either/Either.kt b/either/src/main/kotlin/net/grandcentrix/either/Either.kt index 3d21216..89562cd 100644 --- a/either/src/main/kotlin/net/grandcentrix/either/Either.kt +++ b/either/src/main/kotlin/net/grandcentrix/either/Either.kt @@ -127,6 +127,5 @@ inline fun Either.flatMap(succeeded: (S1) -> Either): * * This function is a shorthand for `fold(onSuccess = { it }, onFailure = onFailure)` (see [fold]). */ -inline fun Either.getOrElse(onFailure: (failure: F) -> S): S { - return fold(succeeded = { it }, failed = onFailure) -} +inline fun Either.getOrElse(onFailure: (failure: F) -> S): S = + fold(succeeded = { it }, failed = onFailure) \ No newline at end of file From 3a8ac22f806931e32a7173228192df4c51f12d5b Mon Sep 17 00:00:00 2001 From: Lucas Riedhammer Date: Wed, 24 Feb 2021 11:28:47 +0100 Subject: [PATCH 4/7] change tests names --- .../kotlin/net/grandcentrix/either/EitherTest.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt b/either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt index d34416d..c2f1360 100644 --- a/either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt +++ b/either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt @@ -186,34 +186,34 @@ class EitherTest { } @Test - fun `when isSuccess on success return false`() { + fun `when success then isSuccess returns true`() { assertTrue(Success("success result").isSuccess) } @Test - fun `when isSuccess on failure return false`() { + fun `when failure then isSuccess returns false`() { assertFalse(Failure("failure result").isSuccess) } @Test - fun `when isFailure on success should return false`() { + fun `when success then isFailure returns false`() { assertFalse(Success("success result").isFailure) } @Test - fun `when isFailure on failure should return true`() { + fun `when failure then isFailure returns true`() { assertTrue(Failure("failure result").isFailure) } @Test - fun `when getOrElse with no failure should return success`() { + fun `when success then getOrElse returns success value`() { val either: Either = Success("success") val result = either.getOrElse { "else" } assertThat(result).isEqualTo("success") } @Test - fun `when getOrElse with failure should return else block`() { + fun `when success then getOrElse returns else block`() { val either: Either = Failure("failure result") val result = either.getOrElse { "else" } assertThat(result).isEqualTo("else") From ad193de8fd9a3995a0bd4d5f56030714da7b6a90 Mon Sep 17 00:00:00 2001 From: Lucas Riedhammer Date: Thu, 25 Feb 2021 12:54:31 +0100 Subject: [PATCH 5/7] fix test name --- either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt b/either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt index c2f1360..1fddf5a 100644 --- a/either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt +++ b/either/src/test/kotlin/net/grandcentrix/either/EitherTest.kt @@ -213,7 +213,7 @@ class EitherTest { } @Test - fun `when success then getOrElse returns else block`() { + fun `when failure then getOrElse returns else block`() { val either: Either = Failure("failure result") val result = either.getOrElse { "else" } assertThat(result).isEqualTo("else") From 7fd5e3ef4248a1732276da6294dc5bf3fcabc278 Mon Sep 17 00:00:00 2001 From: Lucas Riedhammer Date: Thu, 25 Feb 2021 12:57:12 +0100 Subject: [PATCH 6/7] Improve documentation --- .../src/main/kotlin/net/grandcentrix/either/Either.kt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/either/src/main/kotlin/net/grandcentrix/either/Either.kt b/either/src/main/kotlin/net/grandcentrix/either/Either.kt index 89562cd..56a380d 100644 --- a/either/src/main/kotlin/net/grandcentrix/either/Either.kt +++ b/either/src/main/kotlin/net/grandcentrix/either/Either.kt @@ -70,14 +70,12 @@ sealed class Either { } /** - * Returns `true` if this instance represents a successful outcome. - * In this case [isFailure] returns `false`. + * Returns `true` if this instance represents a successful outcome, `false` otherwise. */ val isSuccess: Boolean get() = this is Success /** - * Returns `true` if this instance represents a failed outcome. - * In this case [isSuccess] returns `false`. + * Returns `true` if this instance represents a failed outcome, `false` otherwise. */ val isFailure: Boolean get() = this is Failure @@ -125,7 +123,7 @@ inline fun Either.flatMap(succeeded: (S1) -> Either): * Returns the encapsulated value if this instance represents [success][Either.isSuccess] or the * result of [onFailure] function for the encapsulated [Failure] if it is [failure][Either.isFailure]. * - * This function is a shorthand for `fold(onSuccess = { it }, onFailure = onFailure)` (see [fold]). + * This function is a shorthand for `fold(failed = onFailure, succeeded = { it })` (see [fold]). */ inline fun Either.getOrElse(onFailure: (failure: F) -> S): S = - fold(succeeded = { it }, failed = onFailure) \ No newline at end of file + fold(failed = onFailure, succeeded = { it }) \ No newline at end of file From a894e60d9dce92c98133794e3b9b3824c1c60796 Mon Sep 17 00:00:00 2001 From: Lucas Riedhammer Date: Thu, 25 Feb 2021 13:01:06 +0100 Subject: [PATCH 7/7] add documentation for isSuccess and isFailure --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index aaee153..88ef13c 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ As all functions are `inline` they can be used with suspending functions as well Also the following helpers exist: ```kotlin +isSuccess // property returning true if this instance represents a successful outcome, `false` otherwise. +isFailure // property returning true if this instance represents a failed outcome, `false` otherwise. successOrNull // property returning the success value if Success or null if Failure failureOrNull // property returning the failure value if Failure or null if Success onSuccess {} // executes given code block as side effect if Success and returns passed Either value unchanged