package net.ranides.assira.functional;

import lombok.experimental.UtilityClass;
import net.ranides.assira.functional.Consumers.*;

import java.util.function.BiConsumer;
import java.util.function.Consumer;

/**
 * Static functional methods for Consumer interface
 */
@UtilityClass
public class ConsumerUtils {

    /**
     * Sneaky raw cast.
     * It allows to avoid warnings in contexts where we know correctness of the code.
     *
     * @param predicate predicate
     * @return functional
     *
     */
    public static Consumer0 raw(Runnable predicate) {
        return predicate::run;
    }

    /**
     * Sneaky raw cast.
     * It allows to avoid warnings in contexts where we know correctness of the code.
     *
     * @param predicate predicate
     * @param <R> R
     * @return functional
     */
    @SuppressWarnings("unchecked")
    public static <R> Consumer1<R> raw(Consumer<?> predicate) {
        Consumer<R> ready = Consumer.class.cast(predicate);
        return ready::accept;
    }

    /**
     * Sneaky raw cast.
     * It allows to avoid warnings in contexts where we know correctness of the code.
     *
     * @param predicate predicate
     * @param <T> T
     * @param <U> U
     * @return functional
     */
    @SuppressWarnings("unchecked")
    public static <T, U> Consumer2<T, U> raw(BiConsumer<?, ?> predicate) {
        BiConsumer<T, U> ready = BiConsumer.class.cast(predicate);
        return ready::accept;
    }

    /**
     * Sneaky raw cast.
     * It allows to avoid warnings in contexts where we know correctness of the code.
     *
     * @param predicate predicate
     * @param <A> A
     * @param <B> B
     * @param <C> C
     * @return functional
     */
    @SuppressWarnings("unchecked")
    public static <A, B, C> Consumer3<A, B, C> raw(Consumer3<?, ?, ?> predicate) {
        return Consumer3.class.cast(predicate);
    }

    /**
     * Sneaky raw cast.
     * It allows to avoid warnings in contexts where we know correctness of the code.
     *
     * @param function function
     * @param <A> A
     * @param <B> B
     * @param <C> C
     * @param <D> D
     * @return functional
     */
    @SuppressWarnings("unchecked")
    public static <A, B, C, D> Consumer4<A, B, C, D> raw(Consumer4<?, ?, ?, ?> function) {
        return Consumer4.class.cast(function);
    }

}
