package io.gitlab.jfronny.commons.throwable; import io.gitlab.jfronny.commons.tuple.Tuple; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Function; @FunctionalInterface public interface ThrowingBiFunction { R apply(T var1, U var2) throws TEx; @Contract(pure = true) @NotNull @ApiStatus.NonExtendable default ThrowingFunction, R, TEx> fromTuple() { return (t) -> this.apply(t.left(), t.right()); } @Contract(pure = true) @NotNull @ApiStatus.NonExtendable default ThrowingFunction compose(@NotNull ThrowingFunction left, @NotNull ThrowingFunction right) { Objects.requireNonNull(left); Objects.requireNonNull(right); return (t) -> this.apply(left.apply(t), right.apply(t)); } @Contract(pure = true) @NotNull @ApiStatus.NonExtendable default ThrowingBiFunction biCompose(@NotNull ThrowingFunction left, @NotNull ThrowingFunction right) { Objects.requireNonNull(left); Objects.requireNonNull(right); return (l, r) -> this.apply(left.apply(l), right.apply(r)); } @Contract(pure = true) @NotNull @ApiStatus.NonExtendable default ThrowingBiFunction composeLeft(@NotNull ThrowingFunction before) { Objects.requireNonNull(before); return (l, r) -> this.apply(before.apply(l), r); } @Contract(pure = true) @NotNull @ApiStatus.NonExtendable default ThrowingBiFunction composeRight(@NotNull ThrowingFunction before) { Objects.requireNonNull(before); return (l, r) -> this.apply(l, before.apply(r)); } @Contract(pure = true) @NotNull @ApiStatus.NonExtendable default ThrowingBiFunction andThen(@NotNull ThrowingFunction after) { Objects.requireNonNull(after); return (t, u) -> after.apply(this.apply(t, u)); } @Contract(pure = true) @NotNull @ApiStatus.NonExtendable default ThrowingBiConsumer andThen(@NotNull ThrowingConsumer after) { Objects.requireNonNull(after); return (t, u) -> after.accept(this.apply(t, u)); } @Contract(pure = true) @NotNull @ApiStatus.NonExtendable default BiFunction addHandler(@NotNull Function handler) { Objects.requireNonNull(handler); return (t, u) -> { try { return this.apply(t, u); } catch (Throwable e) { return handler.apply(e); } }; } @Contract(pure = true) @NotNull @ApiStatus.NonExtendable default BiFunction addHandler(@NotNull Class exception, @NotNull Function handler) { Objects.requireNonNull(handler); return (t, u) -> { try { return this.apply(t, u); } catch (Throwable e) { if (exception.isAssignableFrom(e.getClass())) return handler.apply((TEx) e); else throw Try.runtimeException(e); } }; } @Contract(pure = true) @NotNull @ApiStatus.NonExtendable default BiFunction orThrow() { return (t, u) -> { try { return this.apply(t, u); } catch (Throwable e) { throw Try.runtimeException(e); } }; } }