unaryOperator) {
+ return unaryOperator;
+ }
+}
diff --git a/src/main/java/io/github/suppierk/java/lang/ThrowableRunnable.java b/src/main/java/io/github/suppierk/java/lang/ThrowableRunnable.java
new file mode 100644
index 0000000..32eb219
--- /dev/null
+++ b/src/main/java/io/github/suppierk/java/lang/ThrowableRunnable.java
@@ -0,0 +1,54 @@
+package io.github.suppierk.java.lang;
+
+import io.github.suppierk.java.util.ExceptionSuppressor;
+
+/**
+ * The {@code Runnable} interface should be implemented by any class whose instances are intended to
+ * be executed by a thread. The class must define a method of no arguments called {@code run}.
+ *
+ * This interface is designed to provide a common protocol for objects that wish to execute code
+ * while they are active. For example, {@code Runnable} is implemented by class {@code Thread}.
+ * Being active simply means that a thread has been started and has not yet been stopped.
+ *
+ *
In addition, {@code Runnable} provides the means for a class to be active while not
+ * subclassing {@code Thread}. A class that implements {@code Runnable} can run without subclassing
+ * {@code Thread} by instantiating a {@code Thread} instance and passing itself in as the target. In
+ * most cases, the {@code Runnable} interface should be used if you are only planning to override
+ * the {@code run()} method and no other {@code Thread} methods. This is important because classes
+ * should not be subclassed unless the programmer intends on modifying or enhancing the fundamental
+ * behavior of the class.
+ *
+ *
Permits checked exceptions unlike {@link Runnable}
+ */
+@FunctionalInterface
+@SuppressWarnings("squid:S112")
+public interface ThrowableRunnable extends Runnable {
+ /**
+ * When an object implementing interface {@code ThrowableRunnable} is used to create a thread,
+ * starting the thread causes the object's {@code run} method to be called in that separately
+ * executing thread.
+ *
+ *
The general contract of the method {@code run} is that it may take any action whatsoever.
+ *
+ * @see java.lang.Thread#run()
+ * @throws Throwable occurred during processing
+ */
+ void runUnsafe() throws Throwable;
+
+ /**
+ * When an object implementing interface {@code Runnable} is used to create a thread, starting the
+ * thread causes the object's {@code run} method to be called in that separately executing thread.
+ *
+ *
The general contract of the method {@code run} is that it may take any action whatsoever.
+ *
+ * @see java.lang.Thread#run()
+ */
+ @Override
+ default void run() {
+ try {
+ runUnsafe();
+ } catch (Throwable throwable) {
+ ExceptionSuppressor.asUnchecked(throwable);
+ }
+ }
+}
diff --git a/src/main/java/io/github/suppierk/java/util/function/ThrowableBiFunction.java b/src/main/java/io/github/suppierk/java/util/function/ThrowableBiFunction.java
index 2a1a0e1..dd64638 100644
--- a/src/main/java/io/github/suppierk/java/util/function/ThrowableBiFunction.java
+++ b/src/main/java/io/github/suppierk/java/util/function/ThrowableBiFunction.java
@@ -32,7 +32,7 @@
* Represents a function that accepts two arguments and produces a result. This is the two-arity
* specialization of {@link Function}.
*
- *
Permits checked exceptions unlike {@link ThrowableBiFunction}
+ *
Permits checked exceptions unlike {@link BiFunction}
*
*
This is a functional interface whose functional method is
* {@link #apply(Object, Object)}.
diff --git a/src/main/java/io/github/suppierk/java/util/function/ThrowableBinaryOperator.java b/src/main/java/io/github/suppierk/java/util/function/ThrowableBinaryOperator.java
index 368d805..b1ad242 100644
--- a/src/main/java/io/github/suppierk/java/util/function/ThrowableBinaryOperator.java
+++ b/src/main/java/io/github/suppierk/java/util/function/ThrowableBinaryOperator.java
@@ -24,9 +24,11 @@
package io.github.suppierk.java.util.function;
+import io.github.suppierk.java.util.ExceptionSuppressor;
import java.util.Comparator;
import java.util.Objects;
import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
import java.util.function.UnaryOperator;
/**
@@ -34,7 +36,7 @@
* as the operands. This is a specialization of {@link BiFunction} for the case where the operands
* and the result are all of the same type.
*
- *
Permits checked exceptions unlike {@link java.util.function.BinaryOperator}
+ *
Permits checked exceptions unlike {@link BinaryOperator}
*
*
This is a functional interface whose functional method is
* {@link #apply(Object, Object)}.
@@ -45,7 +47,31 @@
*/
@FunctionalInterface
@SuppressWarnings("squid:S112")
-public interface ThrowableBinaryOperator extends ThrowableBiFunction {
+public interface ThrowableBinaryOperator extends BinaryOperator {
+ /**
+ * Applies this function to the given argument.
+ *
+ * @param t the function argument
+ * @return the function result
+ * @throws Throwable occurred during processing
+ */
+ T applyUnsafe(T t, T t2) throws Throwable;
+
+ /**
+ * Applies this function to the given arguments.
+ *
+ * @param t the function argument
+ * @return the function result
+ */
+ @Override
+ default T apply(T t, T t2) {
+ try {
+ return applyUnsafe(t, t2);
+ } catch (Throwable throwable) {
+ return ExceptionSuppressor.asUnchecked(throwable);
+ }
+ }
+
/**
* Returns a {@link ThrowableBinaryOperator} which returns the lesser of two elements according to
* the specified {@code Comparator}.
diff --git a/src/main/java/io/github/suppierk/java/util/function/ThrowableUnaryOperator.java b/src/main/java/io/github/suppierk/java/util/function/ThrowableUnaryOperator.java
index e77c962..3d98e31 100644
--- a/src/main/java/io/github/suppierk/java/util/function/ThrowableUnaryOperator.java
+++ b/src/main/java/io/github/suppierk/java/util/function/ThrowableUnaryOperator.java
@@ -24,12 +24,16 @@
package io.github.suppierk.java.util.function;
+import io.github.suppierk.java.util.ExceptionSuppressor;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
/**
* Represents an operation on a single operand that produces a result of the same type as its
* operand. This is a specialization of {@code Function} for the case where the operand and result
* are of the same type.
*
- * Permits checked exceptions unlike {@link java.util.function.UnaryOperator}
+ *
Permits checked exceptions unlike {@link UnaryOperator}
*
*
This is a functional interface whose functional method is
* {@link #apply(Object)}.
@@ -38,7 +42,34 @@
* @see ThrowableFunction
*/
@FunctionalInterface
-public interface ThrowableUnaryOperator extends ThrowableFunction {
+@SuppressWarnings("squid:S112")
+public interface ThrowableUnaryOperator extends UnaryOperator {
+ /**
+ * Applies this function to the given argument.
+ *
+ * @param t the function argument
+ * @return the function result
+ * @throws Throwable occurred during processing
+ */
+ T applyUnsafe(T t) throws Throwable;
+
+ /**
+ * Applies this function to the given argument.
+ *
+ * Has default implementation in order to make {@link #compose(Function)} and {@link
+ * #andThen(Function)} work.
+ *
+ * @param t the function argument
+ * @return the function result
+ */
+ @Override
+ default T apply(T t) {
+ try {
+ return applyUnsafe(t);
+ } catch (Throwable throwable) {
+ return ExceptionSuppressor.asUnchecked(throwable);
+ }
+ }
/**
* Returns a unary operator that always returns its input argument.
diff --git a/src/test/java/io/github/suppierk/java/util/ThrowableFunctionsCallTest.java b/src/test/java/io/github/suppierk/java/ThrowableFunctionsCallTest.java
similarity index 95%
rename from src/test/java/io/github/suppierk/java/util/ThrowableFunctionsCallTest.java
rename to src/test/java/io/github/suppierk/java/ThrowableFunctionsCallTest.java
index a006a13..4a0810d 100644
--- a/src/test/java/io/github/suppierk/java/util/ThrowableFunctionsCallTest.java
+++ b/src/test/java/io/github/suppierk/java/ThrowableFunctionsCallTest.java
@@ -22,12 +22,14 @@
* SOFTWARE.
*/
-package io.github.suppierk.java.util;
+package io.github.suppierk.java;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import io.github.suppierk.java.lang.ThrowableRunnable;
+import io.github.suppierk.java.util.ThrowableComparator;
import io.github.suppierk.java.util.function.ThrowableBiConsumer;
import io.github.suppierk.java.util.function.ThrowableBiFunction;
import io.github.suppierk.java.util.function.ThrowableBiPredicate;
@@ -117,6 +119,13 @@ static Arguments arg(Executable executable) {
static Stream executables() {
return Stream.of(
+ arg(
+ () ->
+ ((ThrowableRunnable)
+ () -> {
+ throw EXCEPTION;
+ })
+ .run()),
arg(
() ->
((ThrowableBiConsumer)
@@ -131,6 +140,13 @@ static Stream executables() {
throw EXCEPTION;
})
.apply(null, null)),
+ arg(
+ () ->
+ ((ThrowableBinaryOperator)
+ (s, s2) -> {
+ throw EXCEPTION;
+ })
+ .apply(null, null)),
arg(
() ->
ThrowableBinaryOperator.minBy(
@@ -421,6 +437,13 @@ static Stream executables() {
(o1, o2) -> {
throw EXCEPTION;
})
- .compare(null, null)));
+ .compare(null, null)),
+ arg(
+ () ->
+ ((ThrowableUnaryOperator)
+ s -> {
+ throw EXCEPTION;
+ })
+ .apply(null)));
}
}
diff --git a/src/test/java/io/github/suppierk/java/util/TryTest.java b/src/test/java/io/github/suppierk/java/TryTest.java
similarity index 99%
rename from src/test/java/io/github/suppierk/java/util/TryTest.java
rename to src/test/java/io/github/suppierk/java/TryTest.java
index f3f048b..e8cc7b7 100644
--- a/src/test/java/io/github/suppierk/java/util/TryTest.java
+++ b/src/test/java/io/github/suppierk/java/TryTest.java
@@ -22,7 +22,7 @@
* SOFTWARE.
*/
-package io.github.suppierk.java.util;
+package io.github.suppierk.java;
import static org.junit.jupiter.api.Assertions.*;
diff --git a/src/test/java/io/github/suppierk/java/UnsafeFunctionsTest.java b/src/test/java/io/github/suppierk/java/UnsafeFunctionsTest.java
new file mode 100644
index 0000000..51afc5b
--- /dev/null
+++ b/src/test/java/io/github/suppierk/java/UnsafeFunctionsTest.java
@@ -0,0 +1,355 @@
+package io.github.suppierk.java;
+
+import static io.github.suppierk.java.UnsafeFunctions.*;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import io.github.suppierk.java.util.function.*;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.function.Executable;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class UnsafeFunctionsTest {
+ private static final Exception EXCEPTION = new Exception();
+
+ @ParameterizedTest
+ @MethodSource("executables")
+ void assertThatFunctionCanBeCalled(Executable expectedToFail) {
+ assertThrows(Exception.class, expectedToFail, "Failed to do call returning exception");
+ }
+
+ static Arguments arg(Executable executable) {
+ return Arguments.of(executable);
+ }
+
+ static Stream executables() {
+ return Stream.of(
+ arg(
+ () ->
+ unsafeRunnable(
+ () -> {
+ throw EXCEPTION;
+ })
+ .run()),
+ arg(
+ () ->
+ unsafeBiConsumer(
+ (s, s2) -> {
+ throw EXCEPTION;
+ })
+ .accept(null, null)),
+ arg(
+ () ->
+ unsafeBiFunction(
+ (s, s2) -> {
+ throw EXCEPTION;
+ })
+ .apply(null, null)),
+ arg(
+ () ->
+ unsafeBinaryOperator(
+ (s, s2) -> {
+ throw EXCEPTION;
+ })
+ .apply(null, null)),
+ arg(
+ () ->
+ ThrowableBinaryOperator.minBy(
+ unsafeComparator(
+ (o1, o2) -> {
+ throw EXCEPTION;
+ }))
+ .apply(null, null)),
+ arg(
+ () ->
+ ThrowableBinaryOperator.maxBy(
+ unsafeComparator(
+ (o1, o2) -> {
+ throw EXCEPTION;
+ }))
+ .apply(null, null)),
+ arg(
+ () ->
+ unsafeBiPredicate(
+ (s, s2) -> {
+ throw EXCEPTION;
+ })
+ .test(null, null)),
+ arg(
+ unsafeBooleanSupplier(
+ () -> {
+ throw EXCEPTION;
+ })
+ ::getAsBoolean),
+ arg(
+ () ->
+ unsafeConsumer(
+ s -> {
+ throw EXCEPTION;
+ })
+ .accept(null)),
+ arg(
+ () ->
+ unsafeDoubleBinaryOperator(
+ (left, right) -> {
+ throw EXCEPTION;
+ })
+ .applyAsDouble(.0, .0)),
+ arg(
+ () ->
+ unsafeDoubleConsumer(
+ value -> {
+ throw EXCEPTION;
+ })
+ .accept(.0)),
+ arg(
+ () ->
+ unsafeDoubleFunction(
+ value -> {
+ throw EXCEPTION;
+ })
+ .apply(.0)),
+ arg(
+ () ->
+ unsafeDoublePredicate(
+ value -> {
+ throw EXCEPTION;
+ })
+ .test(.0)),
+ arg(
+ unsafeDoubleSupplier(
+ () -> {
+ throw EXCEPTION;
+ })
+ ::getAsDouble),
+ arg(
+ () ->
+ unsafeDoubleToIntFunction(
+ value -> {
+ throw EXCEPTION;
+ })
+ .applyAsInt(.0)),
+ arg(
+ () ->
+ unsafeDoubleToLongFunction(
+ value -> {
+ throw EXCEPTION;
+ })
+ .applyAsLong(.0)),
+ arg(
+ () ->
+ unsafeDoubleUnaryOperator(
+ operand -> {
+ throw EXCEPTION;
+ })
+ .applyAsDouble(.0)),
+ arg(
+ () ->
+ unsafeFunction(
+ s -> {
+ throw EXCEPTION;
+ })
+ .apply(null)),
+ arg(
+ () ->
+ unsafeIntBinaryOperator(
+ (left, right) -> {
+ throw EXCEPTION;
+ })
+ .applyAsInt(0, 0)),
+ arg(
+ () ->
+ unsafeIntConsumer(
+ value -> {
+ throw EXCEPTION;
+ })
+ .accept(0)),
+ arg(
+ () ->
+ unsafeIntFunction(
+ value -> {
+ throw EXCEPTION;
+ })
+ .apply(0)),
+ arg(
+ () ->
+ unsafeIntPredicate(
+ value -> {
+ throw EXCEPTION;
+ })
+ .test(0)),
+ arg(
+ unsafeIntSupplier(
+ () -> {
+ throw EXCEPTION;
+ })
+ ::getAsInt),
+ arg(
+ () ->
+ unsafeIntToDoubleFunction(
+ value -> {
+ throw EXCEPTION;
+ })
+ .applyAsDouble(0)),
+ arg(
+ () ->
+ unsafeIntToLongFunction(
+ value -> {
+ throw EXCEPTION;
+ })
+ .applyAsLong(0)),
+ arg(
+ () ->
+ unsafeIntUnaryOperator(
+ operand -> {
+ throw EXCEPTION;
+ })
+ .applyAsInt(0)),
+ arg(
+ () ->
+ unsafeLongBinaryOperator(
+ (left, right) -> {
+ throw EXCEPTION;
+ })
+ .applyAsLong(0L, 0L)),
+ arg(
+ () ->
+ unsafeLongConsumer(
+ value -> {
+ throw EXCEPTION;
+ })
+ .accept(0L)),
+ arg(
+ () ->
+ unsafeLongFunction(
+ value -> {
+ throw EXCEPTION;
+ })
+ .apply(0L)),
+ arg(
+ () ->
+ unsafeLongPredicate(
+ value -> {
+ throw EXCEPTION;
+ })
+ .test(0L)),
+ arg(
+ unsafeLongSupplier(
+ () -> {
+ throw EXCEPTION;
+ })
+ ::getAsLong),
+ arg(
+ () ->
+ unsafeLongToDoubleFunction(
+ value -> {
+ throw EXCEPTION;
+ })
+ .applyAsDouble(0L)),
+ arg(
+ () ->
+ unsafeLongToIntFunction(
+ value -> {
+ throw EXCEPTION;
+ })
+ .applyAsInt(0L)),
+ arg(
+ () ->
+ unsafeLongUnaryOperator(
+ operand -> {
+ throw EXCEPTION;
+ })
+ .applyAsLong(0L)),
+ arg(
+ () ->
+ unsafeObjDoubleConsumer(
+ (s, value) -> {
+ throw EXCEPTION;
+ })
+ .accept(null, .0)),
+ arg(
+ () ->
+ unsafeObjIntConsumer(
+ (s, value) -> {
+ throw EXCEPTION;
+ })
+ .accept(null, 0)),
+ arg(
+ () ->
+ unsafeObjLongConsumer(
+ (s, value) -> {
+ throw EXCEPTION;
+ })
+ .accept(null, 0L)),
+ arg(
+ () ->
+ unsafePredicate(
+ s -> {
+ throw EXCEPTION;
+ })
+ .test(null)),
+ arg(
+ unsafeSupplier(
+ () -> {
+ throw EXCEPTION;
+ })
+ ::get),
+ arg(
+ () ->
+ unsafeToDoubleBiFunction(
+ (s, s2) -> {
+ throw EXCEPTION;
+ })
+ .applyAsDouble(null, null)),
+ arg(
+ () ->
+ unsafeToDoubleFunction(
+ value -> {
+ throw EXCEPTION;
+ })
+ .applyAsDouble(null)),
+ arg(
+ () ->
+ unsafeToIntBiFunction(
+ (s, s2) -> {
+ throw EXCEPTION;
+ })
+ .applyAsInt(null, null)),
+ arg(
+ () ->
+ unsafeToIntFunction(
+ value -> {
+ throw EXCEPTION;
+ })
+ .applyAsInt(null)),
+ arg(
+ () ->
+ unsafeToLongBiFunction(
+ (s, s2) -> {
+ throw EXCEPTION;
+ })
+ .applyAsLong(null, null)),
+ arg(
+ () ->
+ unsafeToLongFunction(
+ value -> {
+ throw EXCEPTION;
+ })
+ .applyAsLong(null)),
+ arg(
+ () ->
+ unsafeComparator(
+ (o1, o2) -> {
+ throw EXCEPTION;
+ })
+ .compare(null, null)),
+ arg(
+ () ->
+ unsafeUnaryOperator(
+ s -> {
+ throw EXCEPTION;
+ })
+ .apply(null)));
+ }
+}