package scotch.runtime;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* Support methods and classes.
*/
public final class RuntimeSupport {
/**
* Shorthand for creating an {@link Applicable}.
*
* @param function The function to alias into an {@link Applicable}.
* @param <A> The type of the {@link Callable} argument.
* @param <B> The type of the {@link Callable} result.
* @return The appropriate {@link Applicable}.
*/
public static <A, B> Applicable<A, B> applicable(Function<Callable<A>, Callable<B>> function) {
return function::apply;
}
/**
* Boxes a boolean into a {@link Callable}.
*
* @param value The boolean to be boxed.
* @return The boxed boolean.
*/
public static Callable<Boolean> box(boolean value) { return new BoxedCallable<>(value); }
/**
* Boxes a char into a {@link Callable}.
*
* @param value The char to be boxed.
* @return The boxed char.
*/
public static Callable<Character> box(char value) { return new BoxedCallable<>(value); }
/**
* Boxes a double into a {@link Callable}.
*
* @param value The double to be boxed.
* @return The boxed double.
*/
public static Callable<Double> box(double value) {
return new BoxedCallable<>(value);
}
/**
* Boxes an int into a {@link Callable}.
*
* @param value The int to be boxed.
* @return The boxed int.
*/
public static Callable<Integer> box(int value) {
return new BoxedCallable<>(value);
}
/**
* Boxes any Object value into a {@link Callable}.
*
* @param value The value to be boxed.
* @param <A> The type of the value.
* @return The boxed value.
*/
public static <A> Callable<A> box(A value) {
return new BoxedCallable<>(value);
}
/**
* Creates a {@link Thunk} which will execute the given Supplier and store
* the resultant value when called.
*
* @param supplier The supplier giving the value.
* @param <A> The type returned from the supplier.
* @return The thunk.
*/
public static <A> Callable<A> callable(Supplier<A> supplier) {
return new Thunk<A>() {
@Override
protected A evaluate() {
return supplier.get();
}
};
}
/**
* Creates a {@link Thunk} that handles a Supplier returning a {@link Callable}.
*
* @param supplier The supplier returning a {@link Callable}
* @param <A> The type of the value returned from the {@link Callable}
* @return The thunk.
*/
public static <A> Callable<A> flatCallable(Supplier<Callable<A>> supplier) {
return new Thunk<A>() {
@Override
protected A evaluate() {
return supplier.get().call();
}
};
}
/**
* Unboxes a boolean from a {@link Callable}.
*
* @param callable The callable to unbox.
* @return The boolean value.
*/
@SuppressWarnings("unused")
public static boolean unboxBool(Callable<Boolean> callable) {
return callable.call();
}
private RuntimeSupport() {
// intentionally empty
}
/**
* Boxes values into {@link Callable}s.
*
* @param <A> The contained type.
*/
public static final class BoxedCallable<A> implements Callable<A> {
private final A value;
public BoxedCallable(A value) {
this.value = value;
}
@SuppressWarnings("unchecked")
@Override
public A call() {
if (value instanceof Callable) {
return (A) ((Callable) value).call();
} else {
return value;
}
}
}
}