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

ru.progrm_jarvis.javacommons.object.Result Maven / Gradle / Ivy

package ru.progrm_jarvis.javacommons.object;

import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.SneakyThrows;
import lombok.Value;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import ru.progrm_jarvis.javacommons.annotation.Any;

import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * A tagged union representing either a successful result or an error.
 *
 * @param  type of successful result
 * @param  type of error result
 */
@SuppressWarnings("PublicInnerClass")
public interface Result extends Supplier {

    /* ************************************************* Factories ************************************************* */

    /**
     * Creates a new successful result.
     *
     * @param value value of the successful result
     * @param  type of successful result
     * @param  type of error result
     * @return created successful result
     */
    static  @NotNull Result success(final T value) {
        return value == null ? nullSuccess() : new Success<>(value);
    }

    /**
     * Creates a new successful result with {@code null} value.
     *
     * @param  type of successful result
     * @param  type of error result
     * @return created successful result
     */
    @SuppressWarnings("unchecked")
    static  @NotNull Result<@Nullable T, E> nullSuccess() {
        return (Result) NullSuccess.INSTANCE;
    }

    /**
     * Creates a new error result.
     *
     * @param error value of the error result
     * @param  type of successful result
     * @param  type of error result
     * @return created error result
     */
    static  @NotNull Result error(final E error) {
        return error == null ? nullError() : new Error<>(error);
    }

    /**
     * Creates a new {@code void}-error result.
     *
     * @param  type of successful result
     * @param  type of error result
     * @return created error result
     */
    @SuppressWarnings("unchecked")
    static  @NotNull Result nullError() {
        return (Result) NullError.INSTANCE;
    }

    /**
     * Converts the given {@link Optional} into a {@link #nullError() null-error result}.
     *
     * @param optional optional to be converted into the result
     * @param  type of successful result
     * @param  type of error result
     * @return {@link #success(Object) successful result} if the value {@link Optional#isPresent()} in the optional
     * and a {@link #nullError() null-error result} otherwise
     *
     * @see #from(Optional, Supplier) alternative with customizable error value
     */
    @SuppressWarnings("OptionalUsedAsFieldOrParameterType") // convertion from optional itself
    static  @NotNull Result from(final @NonNull Optional optional) {
        return optional.>map(Result::success).orElseGet(Result::nullError);
    }

    /**
     * Converts the given {@link Optional} into an {@link #error(Object) error result}.
     *
     * @param optional optional to be converted into the result
     * @param errorSupplier supplier to create an error
     * if the given {@link Optional} is {@link Optional#empty() empty}
     * @param  type of successful result
     * @param  type of error result
     * @return {@link #success(Object) successful result} if the value {@link Optional#isPresent()} in the optional
     * and an {@link #error(Object) error result} with an error supplied from {@code error supplier} otherwise
     *
     * @see #from(Optional) alternative with default (i.e. null) error
     */
    @SuppressWarnings("OptionalUsedAsFieldOrParameterType") // convertion from optional itself
    static  @NotNull Result from(final @NonNull Optional optional,
                                             final @NonNull Supplier errorSupplier) {
        return optional.>map(Result::success).orElseGet(() -> error(errorSupplier.get()));
    }

    /**
     * Creates a result by calling the specified callable.
     *
     * @param callable provider of the result
     * @param  type of the result provided by the given callable
     * @return {@link #success(Object) successful result} if the callable ran unexceptionally
     * and {@link #error(Object) error result} containing the thrown {@link Exception exception} otherwise
     */
    static  Result tryFrom(final @NonNull Callable callable) {
        final T value;
        try {
            value = callable.call();
        } catch (final Exception x) {
            return error(x);
        }

        return success(value);
    }

    /* ********************************************** Checking methods ********************************************** */

    /**
     * Checks is this result is successful.
     *
     * @return {@code true} if this is a successful result and {@code false} otherwise
     */
    boolean isSuccess();

    /**
     * Checks is this result is an error.
     *
     * @return {@code true} if this is an error result and {@code false} otherwise
     */
    boolean isError();

    /* ********************************************* Unwrapping methods ********************************************* */

    @Override
    default T get() {
        return unwrap();
    }

    /**
     * Gets the value of this result throwing a {@link NotSuccessException}
     * if this is an {@link #isError() error result}.
     *
     * @return successful value of this result
     *
     * @throws NotSuccessException if this is an {@link #isError() error result}
     * @see #expect(String) analog with exception message specification
     * @see #orElseThrow(Function) analog with exception specification
     * @see #orElseSneakyThrow(Function) analog with unchecked exception specification
     */
    T unwrap();

    /**
     * Gets the value of this result throwing a {@link NotSuccessException}
     * if this is an {@link #isError() error result}.
     *
     * @param message message to be specified to {@link NotSuccessException}
     * @return successful value of this result
     *
     * @throws NotSuccessException if this is an {@link #isError() error result}
     * @see #unwrap() analog with default message
     * @see #orElseThrow(Function) analog with exception specification
     * @see #orElseSneakyThrow(Function) analog with unchecked exception specification
     */
    T expect(@NonNull String message);

    /**
     * Gets the value of this result throwing {@code X} got by using the specified supplier
     * if this is an {@link #isError() error result}.
     *
     * @param exceptionFactory factory of a thrown exception consuming the error value of this result
     * @param  type of exception thrown if this is an {@link #isError() error result}
     * @return successful value of this result
     *
     * @throws X if this is an {@link #isError() error result}
     * @see #expect(String) {@link NotSuccessException} analog
     * @see #unwrap() default message {@link NotSuccessException} analog
     * @see #orElseSneakyThrow(Function) unchecked equivalent
     */
     T orElseThrow(@NonNull Function exceptionFactory) throws X;

    /**
     * Gets the value of this result throwing {@code X} got by using the specified supplier
     * if this is an {@link #isError() error result}. Throws {@code X} if this is an {@link #isError() error result}.
     * This differs from {@link #orElseThrow(Function)} as this does not declare {@code X} as a thrown exception.
     *
     * @param exceptionFactory factory of a thrown exception consuming the error value of this result
     * @param  type of exception thrown if this is an {@link #isError() error result}
     * @return successful value of this result
     *
     * @see #expect(String) {@link NotSuccessException} analog
     * @see #unwrap() default message {@link NotSuccessException} analog
     * @see #orElseThrow(Function) checked equivalent
     */
    @SneakyThrows
    default  T orElseSneakyThrow(
            final @NonNull Function exceptionFactory
    ) {
        return orElseThrow(exceptionFactory);
    }

    /**
     * Gets the value of this result if this is a {@link #isSuccess() successful}
     * otherwise returning default value.
     *
     * @param defaultValue default value to be returned if this is an {@link #isError()} error value}
     * @return successful value if this a {@link #isSuccess() successful result} or {@code defaultValue} otherwise
     */
    T orDefault(T defaultValue);

    /**
     * Gets the value of this result if this is a {@link #isSuccess() successful}
     * otherwise returning the value got by using the specified supplier.
     *
     * @param defaultValueSupplier supplier of the default value
     * to be returned if this is an {@link #isError()} error value}
     * @return successful value if this a {@link #isSuccess() successful result} or {@code defaultValue} otherwise
     */
    T orGetDefault(@NonNull Supplier defaultValueSupplier);

    /**
     * Gets the error of this result throwing a {@link NotErrorException}
     * if this is a {@link #isSuccess() successful result}.
     *
     * @return error value of this result
     *
     * @throws NotErrorException if this is a {@link #isSuccess() successful result}
     * @see #expectError(String) analog with exception message specification
     * @see #errorOrElseThrow(Function) analog with exception specification
     * @see #errorOrElseSneakyThrow(Function) analog with unchecked exception specification
     */
    E unwrapError();

    /**
     * Gets the error of this result throwing a {@link NotErrorException}
     * if this is a {@link #isSuccess() successful result}.
     *
     * @param message message to be specified to {@link NotErrorException}
     * @return error value of this result
     *
     * @throws NotErrorException if this is a {@link #isSuccess() successful result}
     * @see #unwrapError() analog with default message
     * @see #errorOrElseThrow(Function) analog with exception specification
     * @see #errorOrElseSneakyThrow(Function) analog with unchecked exception specification
     */
    E expectError(String message);

    /**
     * Gets the error of this result throwing {@code X} got by using the specified supplier
     * if this is a {@link #isSuccess() successful result}.
     *
     * @param exceptionFactory factory of a thrown exception consuming the successful value of this result
     * @param  type of exception thrown if this is a {@link #isSuccess() successful result}
     * @return error value of this result
     *
     * @throws X if this is an {@link #isError() error result}
     * @see #unwrapError() default message {@link NotErrorException} analog
     * @see #expectError(String) {@link NotErrorException} analog
     * @see #errorOrElseSneakyThrow(Function) unchecked equivalent
     */
     E errorOrElseThrow(@NonNull Function exceptionFactory) throws X;

    /**
     * Gets the error of this result throwing {@code X} got by using the specified supplier
     * if this is a {@link #isSuccess() successful result}. Throws {@code X} if this is an {@link #isError() error result}.
     * This differs from {@link #orElseThrow(Function)} as this does not declare {@code X} as a thrown exception.
     *
     * @param exceptionFactory factory of a thrown exception consuming the successful value of this result
     * @param  type of exception thrown if this is a {@link #isSuccess() successful result}
     * @return error value of this result
     *
     * @see #unwrapError() default message {@link NotErrorException} analog
     * @see #expectError(String) {@link NotErrorException} analog
     * @see #errorOrElseThrow(Function) checked equivalent
     */
    @SneakyThrows
    default  E errorOrElseSneakyThrow(
            final @NonNull Function exceptionFactory
    ) {
        return errorOrElseThrow(exceptionFactory);
    }

    /**
     * Invokes the given function if this result is a {@link #isSuccess() successful result}.
     *
     * @param successConsumer consumer accepting the {@link T successful value}
     */
    void ifSuccess(@NonNull Consumer successConsumer);

    /**
     * Invokes the given function if this result is an {@link #isError() error result}.
     *
     * @param errorConsumer consumer accepting the {@link E error value}
     */
    void ifError(@NonNull Consumer errorConsumer);

    /**
     * Invokes the corresponding function depending on this result's type.
     *
     * @param successConsumer consumer accepting the {@link T successful value}
     * @param errorConsumer consumer accepting the {@link E error value}
     */
    void handle(@NonNull Consumer successConsumer, @NonNull Consumer errorConsumer);

    /* ********************************************** Mapping methods ********************************************** */

    /**
     * Maps the result if it is {@link #isSuccess() successful} returning a new result with the result of mapping
     * otherwise keeping the {@link #isError() error result}.
     *
     * @param mappingFunction function to map the successful result
     * @param  type of the resulting successful value
     * @return mapped successful result if it was a {@link #isSuccess() successful result}
     * or an error result if it was an {@link #isError() error result}
     */
     @NotNull Result map(@NonNull Function mappingFunction);

    /**
     * Consumes the result if it is {@link #isSuccess() successful} returning the same result.
     *
     * @param consumer consumer to accept the successful result
     * @return the same result
     */
    @NotNull Result peek(@NonNull Consumer consumer);

    /**
     * Maps the result if it is an {@link #isError() error result} returning a new result with the result of mapping
     * otherwise keeping the {@link #isError() error result}.
     *
     * @param mappingFunction function to map the error result
     * @param  type of the resulting error value
     * @return mapped error result if it was an {@link #isError() an error result}
     * or a successful result if it was a {@link #isError() successful result}
     */
     @NotNull Result mapError(@NonNull Function mappingFunction);

    /**
     * Consumes the result if it is an {@link #isError() error result} returning the same result.
     *
     * @param consumer consumer to accept the successful result
     * @return the same result
     */
    @NotNull Result peekError(@NonNull Consumer consumer);

    /**
     * Returns the given result if this is a {@link #isSuccess() successful result}
     * otherwise keeping the {@link #isError() error result}.
     *
     * @param nextResult result to be returned if this is a {@link #isSuccess() successful result}
     * @param  type of the resulting successful value
     * @return {@code nextResult} if this is a {@link #isSuccess() successful result} or this error result otherwise
     *
     * @see #flatMap(Function) lazy analog
     */
     @NotNull Result and(@NonNull Result nextResult);

    /**
     * Also known as {@code andThen}. Maps the result if this is a {@link #isSuccess() successful result}
     * returning the result of mapping otherwise keeping the {@link #isError() error result}.
     *
     * @param  type of the resulting successful value
     * @param mapper function to create a new result from {@link #unwrap() current successful one}
     * @return mapped {@link #unwrap() successful result} if this was {@link #isSuccess() the one}
     * or this error result otherwise
     *
     * @see #and(Result) non-lazy analog
     */
     @NotNull Result flatMap(@NonNull Function> mapper);

    /**
     * Returns this result if this is a {@link #isSuccess() successful result}
     * otherwise returning the given result.
     *
     * @param alternateResult result to be returned if this is an {@link #isError() error result}
     * @param  type of the resulting error value
     * @return successful result if this is {@link #isSuccess() the one} or {@code alternateResult} otherwise
     *
     * @see #orElse(Function) lazy analog
     */
     @NotNull Result or(@NonNull Result alternateResult);

    /**
     * Maps the result if this is an {@link #isError() error result}
     * returning the result of mapping otherwise keeping the {@link #isSuccess() successful result}.
     *
     * @param mapper function to create a new result from {@link #unwrapError() current error one}
     * @param  type of the resulting error value
     * @return mapped {@link #unwrapError() error result} if this was {@link #isError() the one}
     * or this successful result otherwise
     *
     * @see #or(Result) non-lazy analog
     */
     @NotNull Result orElse(@NonNull Function> mapper);

    /**
     * Swaps this result making an {@link #error(Object) error result} from a {@link #isSuccess() successful result}
     * and a {@link #success(Object) successful result} from an {@link #isError() error result}.
     *
     * @return {@link #error(Object) error result} if this was a {@link #isSuccess() successful result}
     * and a {@link #success(Object) successful result} if this was an {@link #isError() error result}
     */
    @NotNull Result swap();

    /* ********************************************* Conversion methods ********************************************* */

    /**
     * Converts this result to an {@link Optional} of its successful value.
     *
     * @return {@link Optional optional} containing the successful result's value
     * if this is a {@link #isSuccess() successful result}
     * and an {@link Optional#empty() empty optional} otherwise
     */
    @NotNull Optional asOptional();

    /**
     * Converts this result to an {@link Optional} of its error.
     *
     * @return {@link Optional optional} containing the error result's error
     * if this is an {@link #isError() error result}
     * and an {@link Optional#empty() empty optional} otherwise
     */
    @NotNull Optional asErrorOptional();

    /**
     * Converts this result to a {@link ValueContainer} of its successful value.
     *
     * @return {@link ValueContainer value container} containing the successful result's value
     * if this is a {@link #isSuccess() successful result}
     * or an {@link ValueContainer#empty() empty value-container} otherwise
     */
    @NotNull ValueContainer asValueContainer();

    /**
     * Converts this result to a {@link ValueContainer} of its error value.
     *
     * @return {@link ValueContainer value container} containing the error result's error
     * if this is an {@link #isError() error result}
     * or an {@link ValueContainer#empty() empty value-container} otherwise
     */
    @NotNull ValueContainer asErrorValueContainer();

    /**
     * Representation of a {@link #isSuccess() successful} {@link Result result}.
     *
     * @param  type of successful result
     * @param  type of error result
     */
    @Value
    class Success implements Result {

        /**
         * Value wrapped by this result
         */
        T value;

        /**
         * Changes the error type of this result.
         *
         * @param  target error type
         * @return this result with changed error type
         */
        @SuppressWarnings("unchecked")
        private <@Any R> Result transmuteErrorType() {
            return (Result) this;
        }

        //

        @Override
        public boolean isSuccess() {
            return true;
        }

        @Override
        public boolean isError() {
            return false;
        }

        //

        //

        @Override
        public T unwrap() {
            return value;
        }

        @Override
        public T expect(final @NonNull String message) {
            return value;
        }

        @Override
        public  T orElseThrow(final @NonNull Function exceptionFactory) {
            return value;
        }

        @Override
        public T orDefault(final T defaultValue) {
            return value;
        }

        @Override
        public T orGetDefault(final @NonNull Supplier defaultValueSupplier) {
            return value;
        }

        @Override
        public E unwrapError() {
            throw new NotErrorException("This is not an error result");
        }

        @Override
        public E expectError(final String message) {
            throw new NotErrorException(message);
        }

        @Override
        public  E errorOrElseThrow(
                final @NonNull Function exceptionSupplier
        ) throws X {
            throw exceptionSupplier.apply(value);
        }

        @Override
        public void ifSuccess(final @NonNull Consumer successConsumer) {
            successConsumer.accept(value);
        }

        @Override
        public void ifError(final @NonNull Consumer errorConsumer) {}

        @Override
        public void handle(
                final @NonNull Consumer successConsumer,
                final @NonNull Consumer errorConsumer
        ) {
            successConsumer.accept(value);
        }

        //

        //

        @Override
        public  @NotNull Result map(final @NonNull Function mappingFunction) {
            return success(mappingFunction.apply(value));
        }

        @Override
        public @NotNull Result peek(final @NonNull Consumer consumer) {
            consumer.accept(value);

            return this;
        }

        @Override
        public @NotNull <@Any R> Result mapError(
                final @NonNull Function mappingFunction
        ) {
            return transmuteErrorType();
        }

        @Override
        public @NotNull Result peekError(final @NonNull Consumer consumer) {
            return this;
        }

        @Override
        public  @NotNull Result and(final @NonNull Result nextResult) {
            return nextResult;
        }

        @Override
        public  @NotNull Result flatMap(
                final @NonNull Function> mapper
        ) {
            return mapper.apply(value);
        }

        @Override
        public @NotNull <@Any R> Result or(final @NonNull Result alternateResult) {
            return transmuteErrorType();
        }

        @Override
        public @NotNull <@Any R> Result orElse(
                final @NonNull Function> mapper
        ) {
            return transmuteErrorType();
        }

        @Override
        public @NotNull Result swap() {
            return error(value);
        }

        //

        //

        @Override
        public @NotNull Optional asOptional() {
            return Optional.of(value);
        }

        @Override
        public @NotNull Optional asErrorOptional() {
            return Optional.empty();
        }

        @Override
        public @NotNull ValueContainer asValueContainer() {
            return ValueContainer.of(value);
        }

        @Override
        public @NotNull ValueContainer asErrorValueContainer() {
            return ValueContainer.empty();
        }

        //
    }

    /**
     * Representation of an {@link #isError() error} {@link Result result}.
     *
     * @param  type of successful result
     * @param  type of error result
     */
    @Value
    class Error<@Any T, E> implements Result {

        /**
         * Error wrapped by this result
         */
        E error;

        /**
         * Changes the success type of this result.
         *
         * @param  target success type
         * @return this result with changed success type
         */
        @SuppressWarnings("unchecked")
        private <@Any R> Result transmuteResultType() {
            return (Result) this;
        }

        //

        @Override
        public boolean isSuccess() {
            return false;
        }

        @Override
        public boolean isError() {
            return true;
        }

        //

        //

        @Override
        public T unwrap() {
            throw new NotSuccessException("This is not a success-result");
        }

        @Override
        public T expect(final @NonNull String message) {
            throw new NotSuccessException(message);
        }

        @Override
        public  T orElseThrow(
                final @NonNull Function exceptionFactory
        ) throws X {
            throw exceptionFactory.apply(error);
        }

        @Override
        public T orDefault(final T defaultValue) {
            return defaultValue;
        }

        @Override
        public T orGetDefault(final @NonNull Supplier defaultValueSupplier) {
            return defaultValueSupplier.get();
        }

        @Override
        public E unwrapError() {
            return error;
        }

        @Override
        public E expectError(final String message) {
            return error;
        }

        @Override
        public  E errorOrElseThrow(
                final @NonNull Function exceptionFactory
        ) {
            return error;
        }

        @Override
        public void ifSuccess(final @NonNull Consumer successConsumer) {}

        @Override
        public void ifError(final @NonNull Consumer errorConsumer) {
            errorConsumer.accept(error);
        }

        @Override
        public void handle(
                final @NonNull Consumer successConsumer,
                final @NonNull Consumer errorConsumer
        ) {
            errorConsumer.accept(error);
        }
        //

        //

        @Override
        public <@Any R> @NotNull Result map(final @NonNull Function mappingFunction) {
            return transmuteResultType();
        }

        @Override
        public @NotNull Result peek(final @NonNull Consumer consumer) {
            return this;
        }

        @Override
        public @NotNull  Result mapError(final @NonNull Function mappingFunction) {
            return error(mappingFunction.apply(error));
        }

        @Override
        public @NotNull Result peekError(final @NonNull Consumer consumer) {
            consumer.accept(error);

            return this;
        }

        @Override
        public <@Any R> @NotNull Result and(final @NonNull Result nextResult) {
            return transmuteResultType();
        }

        @Override
        public <@Any R> @NotNull Result flatMap(
                final @NonNull Function> mapper
        ) {
            return transmuteResultType();
        }

        @Override
        public @NotNull  Result or(final @NonNull Result alternateResult) {
            return alternateResult;
        }

        @Override
        public @NotNull  Result orElse(
                final @NonNull Function> mapper
        ) {
            return mapper.apply(error);
        }

        @Override
        public @NotNull Result swap() {
            return success(error);
        }

        //

        //

        @Override
        public @NotNull Optional asOptional() {
            return Optional.empty();
        }

        @Override
        public @NotNull Optional asErrorOptional() {
            return Optional.ofNullable(error);
        }

        @Override
        public @NotNull ValueContainer asValueContainer() {
            return ValueContainer.empty();
        }

        @Override
        public @NotNull ValueContainer asErrorValueContainer() {
            return ValueContainer.of(error);
        }

        //
    }

    /**
     * Holder of a {@code null}-success result.
     */
    @UtilityClass
    final class NullSuccess {

        /**
         * Instance of a {@code null}-error
         */
        private final Result<@Nullable ?, ?> INSTANCE = new Success<>(null);
    }

    /**
     * Holder of a {@code null}-error result.
     */
    @UtilityClass
    final class NullError {

        /**
         * Instance of a {@code null}-error
         */
        private final Result INSTANCE = new Error<>(null);
    }

    /**
     * An exception thrown whenever {@link #unwrap()} is called on an error result.
     */
    @NoArgsConstructor
    @SuppressWarnings("PublicConstructor")
    class NotSuccessException extends RuntimeException {
        //

        /**
         * Constructs a new exception with the specified message.
         *
         * @param message message describing the exception cause
         */
        public NotSuccessException(final String message) {
            super(message);
        }

        /**
         * Constructs a new exception with the specified message and cause.
         *
         * @param message message describing the exception cause
         * @param cause cause of this exception
         */
        public NotSuccessException(final String message, final Throwable cause) {
            super(message, cause);
        }

        /**
         * Constructs a new exception with the specified cause.
         *
         * @param cause cause of this exception
         */
        public NotSuccessException(final Throwable cause) {
            super(cause);
        }

        /**
         * Constructs a new exception with the specified message and cause.
         *
         * @param message message describing the exception cause
         * @param cause cause of this exception
         * @param enableSuppression flag indicating whether or not suppression
         * is enabled or disabled for this exception
         * @param writableStackTrace flag indicating whether or not not the stack trace
         * should be writable for this exception
         */
        public NotSuccessException(final String message, final Throwable cause, final boolean enableSuppression,
                                   final boolean writableStackTrace) {
            super(message, cause, enableSuppression, writableStackTrace);
        }

        //
    }

    /**
     * An exception thrown whenever {@link #unwrapError()} is called on a successful result.
     */
    @NoArgsConstructor
    @SuppressWarnings("PublicConstructor")
    class NotErrorException extends RuntimeException {
        //

        /**
         * Constructs a new exception with the specified message.
         *
         * @param message message describing the exception cause
         */
        public NotErrorException(final String message) {
            super(message);
        }

        /**
         * Constructs a new exception with the specified message and cause.
         *
         * @param message message describing the exception cause
         * @param cause cause of this exception
         */
        public NotErrorException(final String message, final Throwable cause) {
            super(message, cause);
        }

        /**
         * Constructs a new exception with the specified cause.
         *
         * @param cause cause of this exception
         */
        public NotErrorException(final Throwable cause) {
            super(cause);
        }

        /**
         * Constructs a new exception with the specified message and cause.
         *
         * @param message message describing the exception cause
         * @param cause cause of this exception
         * @param enableSuppression flag indicating whether or not suppression
         * is enabled or disabled for this exception
         * @param writableStackTrace flag indicating whether or not not the stack trace
         * should be writable for this exception
         */
        public NotErrorException(final String message, final Throwable cause, final boolean enableSuppression,
                                 final boolean writableStackTrace) {
            super(message, cause, enableSuppression, writableStackTrace);
        }

        //
    }

    /**
     * Extensions for Result providing type-specific specializations which are impossible via generic virtual methods.
     */
    @UtilityClass
    class Extensions {

        /**
         * Rethrows the exception if it is an {@link #error(Object) error result}.
         *
         * @param result result to be handled
         * @param  type of the result
         * @param  type of the throwable error
         * @return successful result's value if it was a {@link #isSuccess() successful result}
         * @throws X if it was an {@link #isError() error result}
         */
        public  T rethrow(
                final @NotNull Result result
        ) throws X {
            return result.orElseThrow(Function.identity());
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy