[LANG-1568] Complete FailableFunction.

This commit is contained in:
Gary Gregory 2020-06-25 09:44:22 -04:00
parent 9273b557b7
commit 00c8096cbf
2 changed files with 53 additions and 0 deletions

View File

@ -35,6 +35,17 @@ public interface FailableFunction<T, R, E extends Throwable> {
@SuppressWarnings("rawtypes")
FailableFunction NOP = t -> null;
/**
* Returns a function that always returns its input argument.
*
* @param <T> the type of the input and output objects to the function
* @param <E> Thrown exception.
* @return a function that always returns its input argument
*/
static <T, E extends Throwable> FailableFunction<T, T, E> identity() {
return t -> t;
}
/**
* Returns The NOP singleton.
*
@ -70,4 +81,18 @@ public interface FailableFunction<T, R, E extends Throwable> {
*/
R apply(T input) throws E;
/**
* Returns a composed {@code FailableFunction} like {@link Function#compose(Function)}.
*
* @param <V> the input type to the {@code before} function, and to the composed function.
* @param before the operator to apply before this one.
* @return a a composed {@code FailableFunction} like {@link Function#compose(Function)}.
* @throws NullPointerException if before is null.
* @throws E Thrown when a consumer fails.
* @see #andThen(FailableFunction)
*/
default <V> FailableFunction<V, R, E> compose(final FailableFunction<? super V, ? extends T, E> before) throws E {
Objects.requireNonNull(before);
return (final V v) -> apply(before.apply(v));
}
}

View File

@ -859,6 +859,34 @@ public class FailableFunctionsTest {
assertThrows(NullPointerException.class, () -> failingFunction.andThen(null));
}
@Test
public void testFunctionCompose() throws Throwable {
final Testable<?, ?> testable = new Testable<>(null);
final FailableFunction<Object, Integer, Throwable> failing = t -> {
testable.setThrowable(ERROR);
testable.test();
return 0;
};
final FailableFunction<Object, Integer, Throwable> nop = FailableFunction.nop();
Throwable e = assertThrows(OutOfMemoryError.class, () -> nop.compose(failing).apply(0));
assertSame(ERROR, e);
e = assertThrows(OutOfMemoryError.class, () -> failing.compose(nop).apply(0));
assertSame(ERROR, e);
// Does not throw
nop.compose(nop);
// Documented in Javadoc edge-case.
assertThrows(NullPointerException.class, () -> failing.compose(null));
}
@Test
public void testFunctionIdentity() throws Throwable {
final FailableFunction<Integer, Integer, Throwable> nop = FailableFunction.identity();
// Does not throw
nop.compose(nop);
// Documented in Javadoc edge-case.
assertThrows(NullPointerException.class, () -> nop.compose(null));
}
@Test
public void testGetAsBooleanSupplier() {
final Testable<?, ?> testable = new Testable<>(ILLEGAL_STATE_EXCEPTION);