planetiler/planetiler-core/src/main/java/com/onthegomap/planetiler/util/Try.java

88 wiersze
2.1 KiB
Java

package com.onthegomap.planetiler.util;
import static com.onthegomap.planetiler.util.Exceptions.throwFatalException;
/**
* A container for the result of an operation that may succeed or fail.
*
* @param <T> Type of the result value, if success
*/
public interface Try<T> {
/**
* Calls {@code supplier} and wraps the result in {@link Success} if successful, or {@link Failure} if it throws an
* exception.
*/
static <T> Try<T> apply(SupplierThatThrows<T> supplier) {
try {
return success(supplier.get());
} catch (Exception e) {
return failure(e);
}
}
static <T> Success<T> success(T item) {
return new Success<>(item);
}
static <T> Failure<T> failure(Exception throwable) {
return new Failure<>(throwable);
}
/**
* Returns the result if success, or throws an exception if failure.
*
* @throws IllegalStateException wrapping the exception on failure
*/
T get();
default boolean isSuccess() {
return !isFailure();
}
default boolean isFailure() {
return exception() != null;
}
default Exception exception() {
return null;
}
/** If success, then tries to cast the result to {@code clazz}, turning into a failure if not possible. */
default <O> Try<O> cast(Class<O> clazz) {
return map(clazz::cast);
}
/**
* If this is a success, then maps the value through {@code fn}, returning the new value in a {@link Success} if
* successful, or {@link Failure} if the mapping function threw an exception.
*/
<O> Try<O> map(FunctionThatThrows<T, O> fn);
record Success<T> (T get) implements Try<T> {
@Override
public <O> Try<O> map(FunctionThatThrows<T, O> fn) {
return Try.apply(() -> fn.apply(get));
}
}
record Failure<T> (@Override Exception exception) implements Try<T> {
@Override
public T get() {
return throwFatalException(exception);
}
@Override
@SuppressWarnings("unchecked")
public <O> Try<O> map(FunctionThatThrows<T, O> fn) {
return (Try<O>) this;
}
}
@FunctionalInterface
interface SupplierThatThrows<T> {
@SuppressWarnings("java:S112")
T get() throws Exception;
}
}