java-commons/commons/src/main/java/io/gitlab/jfronny/commons/throwable/ThrowingPredicate.java

150 lines
5.4 KiB
Java

package io.gitlab.jfronny.commons.throwable;
import org.jetbrains.annotations.*;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
@FunctionalInterface
public interface ThrowingPredicate<T, TEx extends Throwable> {
static <T> @NotNull ThrowingPredicate<T, RuntimeException> of(@NotNull Predicate<T> predicate) {
return Objects.requireNonNull(predicate)::test;
}
boolean test(T var1) throws TEx;
@Contract(value = "_ -> new", pure = true)
@ApiStatus.NonExtendable
default <V> @NotNull ThrowingPredicate<V, TEx> compose(@NotNull ThrowingFunction<? super V, ? extends T, ? extends TEx> before) {
Objects.requireNonNull(before);
return (t) -> this.test(before.apply(t));
}
@Contract(value = "_ -> new", pure = true)
@ApiStatus.NonExtendable
default @NotNull ThrowingBooleanSupplier<TEx> compose(@NotNull ThrowingSupplier<? extends T, ? extends TEx> before) {
Objects.requireNonNull(before);
return () -> this.test(before.get());
}
@Contract(value = "_ -> new", pure = true)
@ApiStatus.NonExtendable
default @NotNull ThrowingPredicate<T, TEx> and(@NotNull ThrowingPredicate<? super T, ? extends TEx> other) {
Objects.requireNonNull(other);
return (t) -> this.test(t) && other.test(t);
}
@Contract(value = "_ -> new", pure = true)
@ApiStatus.NonExtendable
default @NotNull ThrowingPredicate<T, TEx> and(@NotNull ThrowingBooleanSupplier<? extends TEx> other) {
Objects.requireNonNull(other);
return (t) -> this.test(t) && other.get();
}
@Contract(value = "_ -> new", pure = true)
@ApiStatus.NonExtendable
default @NotNull ThrowingPredicate<T, TEx> or(@NotNull ThrowingPredicate<? super T, ? extends TEx> other) {
Objects.requireNonNull(other);
return (t) -> this.test(t) || other.test(t);
}
@Contract(value = "_ -> new", pure = true)
@ApiStatus.NonExtendable
default @NotNull ThrowingPredicate<T, TEx> or(@NotNull ThrowingBooleanSupplier<? extends TEx> other) {
Objects.requireNonNull(other);
return (t) -> this.test(t) || other.get();
}
@Contract(value = "_ -> new", pure = true)
@ApiStatus.NonExtendable
default @NotNull ThrowingPredicate<T, TEx> xor(@NotNull ThrowingPredicate<? super T, ? extends TEx> other) {
Objects.requireNonNull(other);
return (t) -> this.test(t) ^ other.test(t);
}
@Contract(value = "_ -> new", pure = true)
@ApiStatus.NonExtendable
default @NotNull ThrowingPredicate<T, TEx> xor(@NotNull ThrowingBooleanSupplier<? extends TEx> other) {
Objects.requireNonNull(other);
return (t) -> this.test(t) ^ other.get();
}
@Contract(value = "-> new", pure = true)
@ApiStatus.NonExtendable
default @NotNull ThrowingPredicate<T, TEx> negate() {
return (t) -> !this.test(t);
}
@Contract(value = "_ -> new", pure = true)
static <T> @NotNull ThrowingPredicate<T, Throwable> isEqual(@Nullable Object targetRef) {
return null == targetRef ? Objects::isNull : targetRef::equals;
}
@Contract(value = "_ -> new", pure = true)
static <T, TEx extends Throwable> @NotNull ThrowingPredicate<T, TEx> not(@NotNull ThrowingPredicate<T, TEx> target) {
return Objects.requireNonNull(target).negate();
}
@Contract(value = "_ -> new", pure = true)
@ApiStatus.NonExtendable
default @NotNull Predicate<T> addHandler(@NotNull Predicate<Throwable> handler) {
Objects.requireNonNull(handler);
return (r) -> {
try {
return this.test(r);
} catch (Throwable e) {
return handler.test(e);
}
};
}
@Contract(value = "_, _ -> new", pure = true)
@ApiStatus.NonExtendable
default @NotNull Predicate<T> addHandler(@NotNull Class<TEx> exception, @NotNull Predicate<TEx> handler) {
Objects.requireNonNull(exception);
Objects.requireNonNull(handler);
return (r) -> {
try {
return this.test(r);
} catch (Throwable e) {
if (exception.isAssignableFrom(e.getClass()))
return handler.test((TEx) e);
else throw ExceptionWrapper.wrap(e);
}
};
}
@Contract(value = "-> new", pure = true)
@ApiStatus.NonExtendable
default @NotNull Predicate<T> orThrow() {
return orThrow(ExceptionWrapper::wrap)::test;
}
@Contract(value = "_ -> new", pure = true)
@ApiStatus.NonExtendable
default <TEx1 extends Throwable> @NotNull ThrowingPredicate<T, TEx1> orThrow(@NotNull Function<Throwable, TEx1> generator) {
Objects.requireNonNull(generator);
return (r) -> {
try {
return this.test(r);
} catch (Throwable e) {
throw generator.apply(e);
}
};
}
/**
* Hides the exception this could throw from the java compiler, effectively making it unchecked.
* Wraps the predicate in a predicate not marked to throw the checked exception.
*
* @return a predicate that does not throw checked exceptions
*/
@Contract(value = "-> new", pure = true)
@ApiStatus.NonExtendable
default Predicate<T> assumeSafe() {
ThrowingPredicate<T, RuntimeException> predicate = (ThrowingPredicate<T, RuntimeException>) (ThrowingPredicate) this;
return predicate::test;
}
}