import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.function.*;
import java.nio.file.*;

// The main method must be in a class named "Main".
class Main {
    public static void main(String[] args) {
        // Example 1: Simple successful operation
        System.out.println("\n1. Simple successful operation:");
        ResultExecutor.Result<Integer, Exception> result1 = ResultExecutor.execute(() -> {
            return 10 + 5;
        });

        System.out.println("Is successful? " + result1.isSuccess());
        System.out.println("Value: " + result1.getValue());

        // Example 2: Operation with error
        System.out.println("\n2. Operation with error:");
        ResultExecutor.Result<Object, Exception> result2 = ResultExecutor.execute(() -> {
            throw new IllegalArgumentException("Invalid value");
        });

        System.out.println("Is successful? " + result2.isSuccess());
        System.out.println("Error: " + result2.getError().getMessage());

        // Example 3: Using orElse
        System.out.println("\n3. Using orElse:");
        ResultExecutor.Result<String, Exception> result3 = ResultExecutor.execute(() -> {
            throw new Exception("Error getting name");
        });

        String name = result3.orElse("Default name");
        System.out.println("Retrieved name: " + name);

        // Example 4: Reading a file (operation that can fail)
        System.out.println("\n4. Trying to read non-existent file:");
        ResultExecutor.Result<List<String>, Exception> result4 = ResultExecutor.execute(() ->
                Files.readAllLines(Path.of("file_that_does_not_exist.txt"))
        );

        if (result4.isSuccess()) {
            System.out.println("Content: " + result4.getValue());
        } else {
            System.out.println("Error reading: " + result4.getError().getClass().getSimpleName()
                    + ": " + result4.getError().getMessage());
        }

        // Example 5: Using onSuccess to chain operations
        System.out.println("\n5. Chaining with onSuccess:");
        ResultExecutor.Result<Integer, Exception> result5 = ResultExecutor.<List<Integer>, Exception>execute(() -> {
            return Arrays.asList(1, 2, 3, 4, 5);
        }).onSuccess(numbers -> {
            int sum = 0;
            for (int num : numbers) {
                sum += num;
            }
            return sum;
        });

        System.out.println("Calculated sum: " + result5.getValue());

        // Example 6: Using fold
        System.out.println("\n6. Using fold:");
        ResultExecutor.Result<Double, ArithmeticException> result6a = ResultExecutor.execute(() ->
                10.0 / 2.0
        );

        String message6a = result6a.fold(
                value -> "Division resulted in: " + value,
                error -> "Error in division: " + error.getMessage()
        );
        System.out.println(message6a);

        ResultExecutor.Result<Double, ArithmeticException> result6b = ResultExecutor.execute(() ->
                10.0 / 0.0
        );

        String message6b = result6b.fold(
                value -> "Division resulted in: " + value,
                error -> "Error in division: " + error.getMessage()
        );
        System.out.println(message6b);

        // Example 7: Using getOrThrow
        System.out.println("\n7. Using getOrThrow:");
        ResultExecutor.Result<String, Exception> result7 = ResultExecutor.execute(() -> "Retrieved value");

        try {
            String value = result7.getOrThrow();
            System.out.println("Value extracted with getOrThrow: " + value);
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }

        // Example 8: Using getOrThrow with exception mapping
        System.out.println("\n8. Using getOrThrow with mapping:");
        ResultExecutor.Result<Object, Exception> result8 = ResultExecutor.execute(() -> {
            throw new FileNotFoundException("Config.xml file not found");
        });

        try {
            Object value = result8.getOrThrow(e ->
                    new RuntimeException("Configuration error: " + e.getMessage(), e)
            );
            System.out.println("This should not be printed: " + value);
        } catch (RuntimeException e) {
            System.out.println("Mapped error: " + e.getMessage());
            System.out.println("Original cause: " + e.getCause().getClass().getSimpleName());
        }
    }
}

final class ResultExecutor {

    private ResultExecutor() {
    }

    @SuppressWarnings("unchecked")
    public static <T, E extends Throwable> Result<T, E> execute(ThrowingSupplier<T, E> action) {
        try {
            return Result.success(action.get());
        } catch (Throwable e) {
            E typedException = (E) e;
            return Result.failure(typedException);
        }
    }

    @SuppressWarnings("unchecked")
    public static <T, E extends Throwable> Result<T, E> execute(ThrowingRunner action) {
        try {
            action.run();
            return Result.success(null);
        } catch (Throwable e) {
            E typedException = (E) e;
            return Result.failure(typedException);
        }
    }

    @FunctionalInterface
    public interface ThrowingSupplier<T, E extends Throwable> {
        T get() throws E;
    }

    @FunctionalInterface
    public interface ThrowingFunction<T, R, E extends Throwable> {
        R apply(T value) throws E;
    }

    @FunctionalInterface
    public interface ThrowingRunner {
        void run() throws Throwable;
    }

    public static class Result<T, E extends Throwable> {
        private final T value;
        private final E error;

        private Result(T value, E error) {
            this.value = value;
            this.error = error;
        }

        public static <T, E extends Throwable> Result<T, E> success(T value) {
            return new Result<>(value, null);
        }

        public static <T, E extends Throwable> Result<T, E> failure(E error) {
            return new Result<>(null, error);
        }

        public T getValue() {
            return value;
        }

        public E getError() {
            return error;
        }

        public boolean isSuccess() {
            return this.error == null;
        }

        public T orElse(T other) {
            if (this.isSuccess()) return this.value;
            return other;
        }

        public Optional<T> asOptional() {
            return isSuccess() ? Optional.of(value) : Optional.empty();
        }

        public T getOrThrow() throws E {
            if (this.isSuccess()) return this.value;
            throw this.error;
        }

        public <X extends Throwable> T getOrThrow(Function<E, X> mapper) throws X {
            if (this.isSuccess()) return this.value;
            throw mapper.apply(this.error);
        }

        @SuppressWarnings("unchecked")
        public <R> Result<R, E> onSuccess(ThrowingFunction<T, R, E> mapper) {
            if (!isSuccess()) return Result.failure(this.error);

            try {
                return Result.success(mapper.apply(value));
            } catch (Throwable e) {
                E typedException = (E) e;
                return Result.failure(typedException);
            }
        }

        public <R> R fold(Function<T, R> onSuccess, Function<E, R> onFailure) {
            return isSuccess() ? onSuccess.apply(value) : onFailure.apply(error);
        }
    }
}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: