diff --git a/common-testing/3RD-PARTY-LICENSES/sbom.xml b/common-testing/3RD-PARTY-LICENSES/sbom.xml index 45033b1..8f60bae 100644 --- a/common-testing/3RD-PARTY-LICENSES/sbom.xml +++ b/common-testing/3RD-PARTY-LICENSES/sbom.xml @@ -17,7 +17,7 @@ common-types io.carbynestack common-types - 0.1-SNAPSHOT + 0.2-SNAPSHOT Apache-2.0 diff --git a/common-testing/src/test/java/io/carbynestack/common/result/FailureTest.java b/common-testing/src/test/java/io/carbynestack/common/result/FailureTest.java index 8965410..4192d62 100644 --- a/common-testing/src/test/java/io/carbynestack/common/result/FailureTest.java +++ b/common-testing/src/test/java/io/carbynestack/common/result/FailureTest.java @@ -58,6 +58,30 @@ void mapAndTransformType() { .hasReason(reason); } + @Test + void tryMap() { + assertThat(result.tryMap(v -> v * 2, reason * 2)).hasReason(reason); + } + + @Test + void tryMapNullPointerException() { + assertThatThrownBy(() -> result.tryMap(null, reason * 2)) + .isExactlyInstanceOf(NullPointerException.class); + } + + @Test + void tryMapAndTransformType() { + assertThat(result.tryMap(v -> String.format("%s * 2 -> %s", v, v * 2), + reason * 2)).hasReason(reason); + } + + @Test + void tryMapWithException() { + assertThat(result.tryMap(v -> { + throw new IOException("-11"); + }, reason * 2)).hasReason(reason); + } + @Test void peek() { AtomicInteger output = new AtomicInteger(-1); @@ -80,11 +104,9 @@ void tryPeek() { @Test void tryPeekWithException() { - Result res = result.tryPeek(v -> { + assertThat(result.tryPeek(v -> { throw new IOException("-11"); - }, reason * 2); - assertThat(res).isFailure(); - assertThat(res).hasReason(reason); + }, reason * 2)).hasReason(reason); } @Test diff --git a/common-testing/src/test/java/io/carbynestack/common/result/SuccessTest.java b/common-testing/src/test/java/io/carbynestack/common/result/SuccessTest.java index ed2fc6f..ff1c3d1 100644 --- a/common-testing/src/test/java/io/carbynestack/common/result/SuccessTest.java +++ b/common-testing/src/test/java/io/carbynestack/common/result/SuccessTest.java @@ -59,6 +59,31 @@ void mapAndTransformType() { .hasValue("12 * 2 -> 24"); } + @Test + void tryMap() { + assertThat(result.tryMap(v -> v * 2, -11)).hasValue(24); + } + + @Test + void tryMapNullPointerException() { + assertThatThrownBy(() -> result.tryMap(null, -11)) + .isExactlyInstanceOf(NullPointerException.class); + } + + @Test + void tryMapAndTransformType() { + assertThat(result.tryMap(v -> String.format("%s * 2 -> %s", v, v * 2), + -11)).hasValue("12 * 2 -> 24"); + } + + @Test + void tryMapWithException() { + int reason = -11; + assertThat(result.tryMap(v -> { + throw new IOException("-11"); + }, reason)).hasReason(reason); + } + @Test void peek() { AtomicInteger output = new AtomicInteger(-1); @@ -82,11 +107,9 @@ void tryPeek() { @Test void tryPeekWithException() { int reason = -11; - Result res = result.tryPeek(v -> { + assertThat(result.tryPeek(v -> { throw new IOException("-11"); - }, reason); - assertThat(res).isFailure(); - assertThat(res).hasReason(reason); + }, reason)).hasReason(reason); } @Test diff --git a/common-types/src/main/java/io/carbynestack/common/result/Failure.java b/common-types/src/main/java/io/carbynestack/common/result/Failure.java index 9b2534e..8e02714 100644 --- a/common-types/src/main/java/io/carbynestack/common/result/Failure.java +++ b/common-types/src/main/java/io/carbynestack/common/result/Failure.java @@ -8,6 +8,7 @@ import io.carbynestack.common.Generated; import io.carbynestack.common.function.AnyThrowingConsumer; +import io.carbynestack.common.function.AnyThrowingFunction; import java.util.Objects; import java.util.Optional; @@ -89,6 +90,28 @@ public Result map(Function function) { return new Failure<>(this.reason()); } + /** + * {@inheritDoc} + * + * @param function the mapping function to apply to a {@link Success#value()} + * @param reason the failure reason in case of the function throwing + * a {@code Throwable} + * @param the success type of the value returned from the mapping + * function + * @return the {@code Result} of mapping the given function to the value + * from this {@link Success} or this {@link Failure} + * @throws NullPointerException if the mapping function is {@code null} + * @version JDK 8 + * @see #recover(Function) + * @see #peek(Consumer) + * @since 0.2.0 + */ + @Override + public Result tryMap(AnyThrowingFunction function, F reason) { + requireNonNull(function); + return new Failure<>(this.reason()); + } + /** * {@inheritDoc} * @@ -272,9 +295,7 @@ public Stream stream() { @Override @Generated public String toString() { - return "Failure{" + - "reason=" + reason + - '}'; + return "Failure{" + "reason=" + reason + '}'; } @Override diff --git a/common-types/src/main/java/io/carbynestack/common/result/Result.java b/common-types/src/main/java/io/carbynestack/common/result/Result.java index c3c3cd2..336974d 100644 --- a/common-types/src/main/java/io/carbynestack/common/result/Result.java +++ b/common-types/src/main/java/io/carbynestack/common/result/Result.java @@ -8,6 +8,7 @@ import io.carbynestack.common.CsFailureReason; import io.carbynestack.common.function.AnyThrowingConsumer; +import io.carbynestack.common.function.AnyThrowingFunction; import io.carbynestack.common.function.AnyThrowingSupplier; import io.carbynestack.common.function.ThrowingSupplier; @@ -159,6 +160,28 @@ default boolean isFailure() { */ Result map(Function function); + /** + * If the {@code Result} is a {@link Success}, returns the result of + * applying the given mapping function to the {@link Success#value()}. + * Otherwise, a cast version of the {@link Failure} is returned. + * + *

In case the function throws a {@link Throwable} the failure reason + * is returned as a {@code Failure}.
+ * + * @param function the mapping function to apply to a {@link Success#value()} + * @param reason the failure reason in case of the function throwing + * a {@code Throwable} + * @param the success type of the value returned from the mapping + * function + * @return the {@code Result} of mapping the given function to the value + * from this {@link Success} or this {@link Failure} + * @throws NullPointerException if the mapping function is {@code null} + * @see #recover(Function) + * @see #peek(Consumer) + * @since 0.2.0 + */ + Result tryMap(AnyThrowingFunction function, F reason); + /** * If the {@code Result} is a {@link Success}, invokes the provided * consumer with the {@link Success#value()}. Otherwise, the diff --git a/common-types/src/main/java/io/carbynestack/common/result/Success.java b/common-types/src/main/java/io/carbynestack/common/result/Success.java index 4959edd..7991b45 100644 --- a/common-types/src/main/java/io/carbynestack/common/result/Success.java +++ b/common-types/src/main/java/io/carbynestack/common/result/Success.java @@ -8,6 +8,7 @@ import io.carbynestack.common.Generated; import io.carbynestack.common.function.AnyThrowingConsumer; +import io.carbynestack.common.function.AnyThrowingFunction; import java.util.Objects; import java.util.Optional; @@ -90,6 +91,33 @@ public Result map(Function function) { return new Success<>((N) function.apply(this.value())); } + /** + * {@inheritDoc} + * + * @param function the mapping function to apply to a {@link Success#value()} + * @param reason the failure reason in case of the function throwing + * a {@code Throwable} + * @param the success type of the value returned from the mapping + * function + * @return the {@code Result} of mapping the given function to the value + * from this {@link Success} or this {@link Failure} + * @throws NullPointerException if the mapping function is {@code null} + * @version JDK 8 + * @see #recover(Function) + * @see #peek(Consumer) + * @since 0.2.0 + */ + @Override + @SuppressWarnings("unchecked") + public Result tryMap(AnyThrowingFunction function, F reason) { + requireNonNull(function); + try { + return new Success<>((N) function.apply(this.value())); + } catch (Throwable throwable) { + return new Failure<>(reason); + } + } + /** * {@inheritDoc} * diff --git a/common-types/src/main/java17/io/carbynestack/common/result/Failure.java b/common-types/src/main/java17/io/carbynestack/common/result/Failure.java index c008ca7..8d0e406 100644 --- a/common-types/src/main/java17/io/carbynestack/common/result/Failure.java +++ b/common-types/src/main/java17/io/carbynestack/common/result/Failure.java @@ -7,6 +7,7 @@ package io.carbynestack.common.result; import io.carbynestack.common.function.AnyThrowingConsumer; +import io.carbynestack.common.function.AnyThrowingFunction; import java.util.Optional; import java.util.function.Consumer; @@ -60,6 +61,28 @@ public Result map(Function function) { return new Failure<>(this.reason()); } + /** + * {@inheritDoc} + * + * @param function the mapping function to apply to a {@link Success#value()} + * @param reason the failure reason in case of the function throwing + * a {@code Throwable} + * @param the success type of the value returned from the mapping + * function + * @return the {@code Result} of mapping the given function to the value + * from this {@link Success} or this {@link Failure} + * @throws NullPointerException if the mapping function is {@code null} + * @version JDK 17 + * @see #recover(Function) + * @see #peek(Consumer) + * @since 0.2.0 + */ + @Override + public Result tryMap(AnyThrowingFunction function, F reason) { + requireNonNull(function); + return new Failure<>(this.reason()); + } + /** * {@inheritDoc} * diff --git a/common-types/src/main/java17/io/carbynestack/common/result/Result.java b/common-types/src/main/java17/io/carbynestack/common/result/Result.java index 6110478..eadf726 100644 --- a/common-types/src/main/java17/io/carbynestack/common/result/Result.java +++ b/common-types/src/main/java17/io/carbynestack/common/result/Result.java @@ -9,6 +9,7 @@ import io.carbynestack.common.CsFailureReason; import io.carbynestack.common.function.AnyThrowingConsumer; import io.carbynestack.common.function.AnyThrowingSupplier; +import io.carbynestack.common.function.AnyThrowingFunction; import io.carbynestack.common.function.ThrowingSupplier; import java.util.Map; @@ -159,6 +160,28 @@ default boolean isFailure() { */ Result map(Function function); + /** + * If the {@code Result} is a {@link Success}, returns the result of + * applying the given mapping function to the {@link Success#value()}. + * Otherwise, a cast version of the {@link Failure} is returned. + * + *

In case the function throws a {@link Throwable} the failure reason + * is returned as a {@code Failure}.
+ * + * @param function the mapping function to apply to a {@link Success#value()} + * @param reason the failure reason in case of the function throwing + * a {@code Throwable} + * @param the success type of the value returned from the mapping + * function + * @return the {@code Result} of mapping the given function to the value + * from this {@link Success} or this {@link Failure} + * @throws NullPointerException if the mapping function is {@code null} + * @see #recover(Function) + * @see #peek(Consumer) + * @since 0.2.0 + */ + Result tryMap(AnyThrowingFunction function, F reason); + /** * If the {@code Result} is a {@link Success}, invokes the provided * consumer with the {@link Success#value()}. Otherwise, the diff --git a/common-types/src/main/java17/io/carbynestack/common/result/Success.java b/common-types/src/main/java17/io/carbynestack/common/result/Success.java index 3b0c397..654b7f6 100644 --- a/common-types/src/main/java17/io/carbynestack/common/result/Success.java +++ b/common-types/src/main/java17/io/carbynestack/common/result/Success.java @@ -7,6 +7,7 @@ package io.carbynestack.common.result; import io.carbynestack.common.function.AnyThrowingConsumer; +import io.carbynestack.common.function.AnyThrowingFunction; import java.util.Optional; import java.util.function.Consumer; @@ -61,6 +62,33 @@ public Result map(Function function) { return new Success<>((N) function.apply(this.value())); } + /** + * {@inheritDoc} + * + * @param function the mapping function to apply to a {@link Success#value()} + * @param reason the failure reason in case of the function throwing + * a {@code Throwable} + * @param the success type of the value returned from the mapping + * function + * @return the {@code Result} of mapping the given function to the value + * from this {@link Success} or this {@link Failure} + * @throws NullPointerException if the mapping function is {@code null} + * @version JDK 17 + * @see #recover(Function) + * @see #peek(Consumer) + * @since 0.2.0 + */ + @Override + @SuppressWarnings("unchecked") + public Result tryMap(AnyThrowingFunction function, F reason) { + requireNonNull(function); + try { + return new Success<>((N) function.apply(this.value())); + } catch (Throwable throwable) { + return new Failure<>(reason); + } + } + /** * {@inheritDoc} * diff --git a/common-types/src/test/java/io/carbynestack/common/result/ResultTest.java b/common-types/src/test/java/io/carbynestack/common/result/ResultTest.java index e11644b..468e58a 100644 --- a/common-types/src/test/java/io/carbynestack/common/result/ResultTest.java +++ b/common-types/src/test/java/io/carbynestack/common/result/ResultTest.java @@ -88,6 +88,17 @@ void tryPeek() { .isFailure()).isTrue(); } + @Test + void tryMap() { + assertThat(new Success<>(12) + .tryMap(v -> v * 2, -11) + .tryMap(v -> { + throw new RuntimeException(); + }, -21) + .tryMap(v -> v * 2, -11) + .isFailure()).isTrue(); + } + @Test void of() { var value = 12;