All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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;
	}
}