package net.ranides.assira.reflection.impl;

import lombok.RequiredArgsConstructor;

import lombok.experimental.UtilityClass;
import net.ranides.assira.functional.special.AnyFunction;
import net.ranides.assira.reflection.*;

/**
 * This class groups helper classes used to dynamic dispatch
 */
@UtilityClass
public class CDispatchFunctions {

    /**
     * This is trivial multiple dispatch implementation.
     *
     * It iterates through all provided methods and calls first one which
     * accepts provided arguments.
     */
    @RequiredArgsConstructor
    public static final class SimpleCall implements AnyFunction<Object> {

        private final IExecutables<?> exec;

        @Override
        public Object apply(Object[] arguments) {
            for (IExecutable e : exec) {
                if (e.accepts(arguments)) {
                    return e.apply(arguments);
                }
            }
            throw new IReflectiveException("Can't dispatch method");
        }
    }

}
