package org.implab.gradle.common.utils;

import java.util.function.Consumer;
import java.util.function.Function;

public class Exceptions {
    /**
     * Helper function which declares that this block can throw the specified
     * exception.
     *
     * @param <E>
     * @param clazz
     * @throws E
     */
    @SuppressWarnings("unused")
    public static <E extends Throwable> void mayThrow(Class<E> clazz) throws E {
    }

    @SuppressWarnings("unchecked")
    public static <E extends Throwable> E sneakyThrow(Throwable t) throws E {
        throw (E) t;
    }

    public static <T, U> Function<T, U> unchecked(ThrowingFunction<T, U> fn) {
        return val -> {
            try {
                return fn.apply(val);
            } catch (Exception e) {
                throw sneakyThrow(e);
            }
        };
    }

    public static <T> Consumer<T> unchecked(ThrowingConsumer<T> c)  {
        return val -> {
            try {
                c.accept(val);
            } catch (Exception e) {
                throw sneakyThrow(e);
            }
        };
    }

    public interface ThrowingConsumer<T> {
        void accept(T value) throws Exception;
    }

    public interface ThrowingFunction<T, U> {
        U apply(T value) throws Exception;
    }
}
