Skip to content

Instantly share code, notes, and snippets.

@Amejonah1200
Created June 17, 2021 20:55
Show Gist options
  • Save Amejonah1200/868feee9318ae9f52925225f562201f3 to your computer and use it in GitHub Desktop.
Save Amejonah1200/868feee9318ae9f52925225f562201f3 to your computer and use it in GitHub Desktop.
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.function.*;
public class Result<T, E extends Throwable> {
private final T obj;
private final E error;
private Result(T obj, E error) {
this.obj = obj;
this.error = error;
}
public Result(@NotNull T obj) {
this(Objects.requireNonNull(obj, "obj cannot be null!"), null);
}
public Result(@NotNull E error) {
this(null, Objects.requireNonNull(error, "error cannot be null!"));
}
/**
* @param def Default nonnull value.
*
* @return If successful
*/
@NotNull
public T getOrDefault(@NotNull T def) {
return obj == null ? Objects.requireNonNull(def) : obj;
}
@Nullable
public T getObj() {
return obj;
}
@Nullable
public E getError() {
return error;
}
public void execute(@NotNull BiConsumer<@Nullable T, @Nullable E> consumer) {
consumer.accept(obj, error);
}
public void execute(@NotNull Consumer<@NotNull T> success, @NotNull Consumer<@NotNull E> failure) {
if (obj != null) success.accept(obj);
else failure.accept(error);
}
public void executeIfSuccessful(@NotNull Consumer<@NotNull T> consumer) {
if (obj != null) consumer.accept(obj);
}
public void executeIfFailed(@NotNull Consumer<@NotNull E> consumer) {
if (error != null) consumer.accept(error);
}
public boolean isSuccessful() {
return obj != null;
}
@NotNull
public <R> Result<R, E> apply(@NotNull Function<@NotNull T, @NotNull R> success, @NotNull Function<@NotNull E, @NotNull R> failure) {
return obj != null ? new Result<>(success.apply(obj), error) : new Result<>(failure.apply(error));
}
@NotNull
public <R> Result<R, E> apply(@NotNull BiFunction<@Nullable T, @Nullable E, @NotNull R> function) {
return new Result<>(function.apply(obj, error));
}
@NotNull
public <R> Result<R, E> applyObj(@NotNull Function<@Nullable T, @NotNull R> function) {
return new Result<>(function.apply(obj), error);
}
/**
* Applying - if this is successful - the value stored to a valid nonnull value.
* This should be used to convert a value to another one.
* @param function Function converting the stored value
* @param <R> New Type.
* @return A new Result, if this Result is successful, it will return with the new value,
* if not, it will return with the actual stored exception.
*/
@NotNull
public <R> Result<R, E> applyIfSuccessful(@NotNull Function<@NotNull T, @NotNull R> function) {
return isSuccessful() ? new Result<>(Objects.requireNonNull(function.apply(obj))) : new Result<>(error);
}
/**
* Applying - if there is an error - the error to a valid nonnull value.
* This should be used to handle an exception and returning an valid value.
* @param function Function converting the error to a valid nonnull value.
* @return A new succeeded Result.
*/
@NotNull
public Result<T, E> applyIfFailure(@NotNull Function<@NotNull E, @NotNull T> function) {
return isSuccessful() ? this : new Result<>(Objects.requireNonNull(function.apply(error)));
}
/**
* Accepts a function to convert the result in another type using the exception, it will accept null if this result is successful.
* @param function Function accepting the error, it will accept null if the result is successful, returning a new nullable value.
* @param <R> New Type.
* @return If the function returns null, a new Result containing the error (successful == false) will be returned.
* Else it will return a Result using the return value from the function.
*/
@NotNull
public <R> Result<R, E> applyException(@NotNull Function<@Nullable E, @Nullable R> function) {
R result = function.apply(error);
return result == null ? new Result<>(error) : new Result<>(result);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment