io.datakernel.functional.Try Maven / Gradle / Ivy
package io.datakernel.functional;
import io.datakernel.annotation.Nullable;
import java.util.function.Function;
public final class Try {
@Nullable
private final T result;
@Nullable
private final Throwable throwable;
private Try(@Nullable T result, @Nullable Throwable throwable) {
this.result = result;
this.throwable = throwable;
}
public static Try of(@Nullable T result) {
return new Try<>(result, null);
}
public static Try ofFailure(Throwable throwable) {
return new Try<>(null, throwable);
}
public static Try wrap(ThrowingSupplier computation) {
try {
return new Try<>(computation.get(), null);
} catch (Throwable t) {
return new Try<>(null, t);
}
}
public boolean isSuccess() {
return throwable == null;
}
@Nullable
public T get() throws Throwable {
if (throwable == null) {
return result;
}
throw throwable;
}
@Nullable
public T getOrNull() {
if (throwable == null) {
return result;
}
return null;
}
@Nullable
public Throwable getThrowable() {
return throwable;
}
@SuppressWarnings("unchecked")
private Try mold() {
assert throwable != null : "Trying to mold a successful Try!";
return (Try) this;
}
public Try map(ThrowingFunction function) {
if (throwable == null) {
try {
return new Try<>(function.apply(result), null);
} catch (Throwable t) {
return new Try<>(null, t);
}
}
return mold();
}
public Try flatMap(Function> function) {
if (throwable == null) {
return function.apply(result);
}
return mold();
}
public Try exceptionally(Function function) {
if (throwable != null) {
return new Try<>(function.apply(throwable), null);
}
return this;
}
public Either toEither() {
if (throwable == null) {
return Either.right(result);
}
return Either.left(throwable);
}
@FunctionalInterface
public interface ThrowingSupplier {
@Nullable
T get() throws Throwable;
}
@FunctionalInterface
interface ThrowingFunction {
@Nullable
R apply(@Nullable T arg) throws Throwable;
}
}