io.github.selcukes.collections.Try Maven / Gradle / Ivy
/*
* Copyright (c) Ramesh Babu Prudhvi.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.selcukes.collections;
import lombok.Getter;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
/**
* Represents the result of an operation that may fail with an exception. A
* `Try` instance can either contain a result of type `T` or an exception.
*
* @param The type of the result that can be contained in the `Try`
* instance.
*/
public class Try {
private final T result;
@Getter
private final Exception exception;
/**
* Constructs a new `Try` instance with the given result and exception.
*
* @param result The result of the operation, or `null` if an exception
* was thrown.
* @param exception The exception that was thrown, or `null` if the
* operation succeeded.
*/
private Try(T result, Exception exception) {
this.result = result;
this.exception = exception;
}
/**
* Runs the given `runnable` without throwing any checked exceptions. If the
* `runnable` throws an exception, a `Try` instance with the exception is
* returned.
*
* @param runnable The `CheckedRunnable` to run.
* @return A `Try` instance with the result set to `null` and the
* exception set to the one thrown by the `runnable`.
*/
public static Try of(CheckedRunnable runnable) {
try {
runnable.run();
return new Try<>(null, null);
} catch (Exception e) {
return new Try<>(null, e);
}
}
/**
* Runs the given `supplier` without throwing any checked exceptions. If the
* `supplier` throws an exception, a `Try` instance with the exception is
* returned.
*
* @param supplier The `CheckedSupplier` to run.
* @param The type of the result that can be contained in the
* `Try` instance.
* @return A `Try` instance with the result set to `null` and the
* exception set to the one thrown by the `supplier`.
*/
public static Try of(CheckedSupplier supplier) {
try {
return new Try<>(supplier.get(), null);
} catch (Exception e) {
return new Try<>(null, e);
}
}
/**
* Returns the result of the operation if it was successful, or throws the
* exception wrapped in a runtime exception if the operation failed.
*
* @return the result of the operation if it was successful
* @throws RuntimeException if the operation failed
*/
public T orElseThrow() {
if (isFailure()) {
throw wrapAsRuntimeException(exception);
}
return result;
}
/**
* Returns the result of the operation if it was successful, or throws a
* runtime exception generated by the given error handler if the operation
* failed.
*
* @param errorHandler a function that takes the exception thrown by
* the operation and returns a runtime exception to
* be thrown instead
* @return the result of the operation if it was successful
* @throws RuntimeException if the operation failed
*/
public T orElseThrow(UnaryOperator errorHandler) {
return or(
ex -> {
throw wrapAsRuntimeException(errorHandler.apply(ex));
},
Function.identity());
}
/**
* Invokes the given `supplier` to create a resource of type `T` and applies
* the `resourceMapper` to the resource. The resource is automatically
* closed after the `resourceMapper` is applied.
*
* @param supplier The `CheckedSupplier` to create the resource.
* @param resourceMapper The `CheckedFunction` to apply to the resource.
* @param The type of the resource to create.
* @param The type of the result that can be contained in
* the `Try` instance.
* @return A `Try` instance with the result set to the value
* returned by the `resourceMapper` and the exception
* set to the one caught.
*/
public static Try with(
CheckedSupplier supplier, CheckedFunction resourceMapper
) {
try (T resource = supplier.get()) {
return new Try<>(resourceMapper.apply(resource), null);
} catch (Exception e) {
return new Try<>(null, e);
}
}
/**
* Returns `true` if the operation succeeded (i.e., no exception was
* thrown).
*
* @return `true` if the operation succeeded, `false` otherwise.
*/
public boolean isSuccess() {
return exception == null;
}
/**
* Returns `true` if the operation failed (i.e., an exception was thrown).
*
* @return `true` if the operation failed, `false` otherwise.
*/
public boolean isFailure() {
return exception != null;
}
/**
* Returns the result held by this Try object wrapped in an Optional.
*
* @return an Optional containing the result held by this Try object, or an
* empty Optional if this Try object represents a failure
*/
public Optional getResult() {
return Optional.ofNullable(result);
}
/**
* Applies the given function to the result of this Try, which produces a
* new Try. If this Try contains an exception, a new Try containing the
* exception is returned.
*
* @param mapper the function to apply to the result of this Try
* @param the type of the result of the new Try
* @return a new Try containing the result of the given function or
* an exception
*/
public Try flatMap(Function> mapper) {
if (isFailure()) {
return new Try<>(null, exception);
}
try {
return mapper.apply(result);
} catch (Exception e) {
return new Try<>(null, e);
}
}
/**
* Returns the result of this Try if it contains one, otherwise returns the
* result of the given fallback supplier.
*
* @param fallback the fallback supplier to call if this Try contains an
* exception
* @return the result of this Try if it contains one, otherwise the
* result of the fallback supplier
*/
public T orElse(Supplier fallback) {
return getResult().orElseGet(fallback);
}
/**
* Returns the result of applying the successHandler function to the result
* of this Try if it contains one, otherwise returns the result of applying
* the errorHandler function to the exception contained in this Try.
*
* @param errorHandler the function to apply to the exception contained
* in this Try
* @param successHandler the function to apply to the result of this Try if
* it contains one
* @param the type of the result of the function applied to
* the result of this Try or the exception contained
* in this Try
* @return the result of applying the successHandler function
* to the result of this Try if it contains one,
* otherwise the result of applying the errorHandler
* function to the exception contained in this Try
*/
public R or(Function errorHandler, Function successHandler) {
return isFailure() ? errorHandler.apply(exception) : successHandler.apply(result);
}
/**
* A functional interface representing a function that takes an argument of
* type T and returns a result of type R, and may throw an Exception.
*
* @param the type of the input to the function
* @param the type of the result of the function
*/
@FunctionalInterface
public interface CheckedFunction {
@SuppressWarnings("squid:S112")
R apply(T t) throws Exception;
}
/**
* A functional interface representing a supplier of values of type T, which
* may throw an Exception.
*
* @param the type of results supplied by this supplier
*/
@FunctionalInterface
public interface CheckedSupplier {
@SuppressWarnings("squid:S112")
T get() throws Exception;
}
/**
* A functional interface representing an operation that may throw an
* Exception.
*/
@FunctionalInterface
public interface CheckedRunnable {
@SuppressWarnings("squid:S112")
void run() throws Exception;
}
/**
* Wraps the given Throwable object as a RuntimeException if necessary. If
* the Throwable object is an instance of RuntimeException or one of its
* subtypes, it is returned as-is. If it is an instance of Error, it is
* thrown immediately. Otherwise, a new RuntimeException object is created
* with the Throwable object as its cause, and returned.
*
* @param throwable the Throwable object to wrap as a RuntimeException
* @return a RuntimeException object representing the original
* Throwable
* @throws Error if the Throwable object is an instance of Error
*/
private static RuntimeException wrapAsRuntimeException(Throwable throwable) {
if (throwable instanceof RuntimeException runtimeException) {
return runtimeException;
} else if (throwable instanceof Error error) {
throw error;
} else {
return new RuntimeException(throwable);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy