paxel.lib.Result Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tool-shed Show documentation
Show all versions of tool-shed Show documentation
Grouping Executor for grouped sequential processing
The newest version!
package paxel.lib;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* Rust-like Result
*
* @param the value type of the Result.
* @param the error type of the Result.
*/
public record Result(V value, E error, ResultStatus status) {
public static Result ok(V value) {
return new Result<>(value, null, ResultStatus.SUCCESS);
}
public static Result err(E error) {
return new Result<>(null, error, ResultStatus.FAIL);
}
public boolean isSuccess() {
return status.isSuccess();
}
public boolean hasFailed() {
return !status.isSuccess();
}
@Override
public V value() {
return switch (status) {
case SUCCESS -> value;
default -> throw new ResultException(String.format("No value in Result. Error was %s", verboseError()));
};
}
public V getValueOr(V fallBack) {
return switch (status) {
case SUCCESS -> value;
default -> fallBack;
};
}
public V getValueOrGet(Supplier fallBack) {
return switch (status) {
case SUCCESS -> value;
default -> fallBack.get();
};
}
public Result map(Function valueMapper, Function errorMapper) {
return switch (status) {
case SUCCESS -> Result.ok(valueMapper.apply(value));
default -> Result.err(errorMapper.apply(error));
};
}
public Result mapValue(Function valueMapper) {
return switch (status) {
case SUCCESS -> Result.ok(valueMapper.apply(value));
default ->
throw new IllegalStateException(String.format("Can't map the value of a failed Result. Error was %s", verboseError()));
};
}
public Result mapResult(Function, Result> valueMapper) {
return valueMapper.apply(this);
}
public Result mapValueToError(Function valueToErrorMapper) {
return Result.err(valueToErrorMapper.apply(value));
}
/**
* Creates a new Result with a new Error.
*
* @param errorMapper creates a new Error from the existing one.
* @return the new Status
*/
public Result mapError(Function errorMapper) {
return switch (status) {
case FAIL -> Result.err(errorMapper.apply(error));
default ->
throw new IllegalStateException(String.format("Can't map the error of a successful Result. Value was %s", verboseValue()));
};
}
private String verboseValue() {
return switch (value) {
case null -> " value";
default -> String.format("%s: %s", value.getClass().getSimpleName(), value);
};
}
private String verboseError() {
return switch (error) {
case null -> " error";
default -> String.format("%s: %s", error.getClass().getSimpleName(), error);
};
}
/**
* Retrieve the Error.
*
* @return the Error
* @throws ResultException if the Result is successful.
*/
@Override
public E error() {
return switch (status) {
case FAIL -> error;
default -> throw new ResultException("No error in Result. Value was " + value);
};
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Result, ?> result))
return false;
if (!Objects.equals(value, result.value))
return false;
if (!Objects.equals(error, result.error))
return false;
return status == result.status;
}
@Override
public int hashCode() {
int result = value != null ? value.hashCode() : 0;
result = 31 * result + (error != null ? error.hashCode() : 0);
result = 31 * result + status.hashCode();
return result;
}
public enum ResultStatus {
FAIL(false), SUCCESS(true);
private final boolean success;
ResultStatus(boolean success) {
this.success = success;
}
public boolean isSuccess() {
return this.success;
}
}
@Override
public String toString() {
return switch (status) {
case SUCCESS -> "SUCCESS:" + verboseError();
default -> "FAILURE:" + verboseValue();
};
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy