001/*
002 * PermissionsEx
003 * Copyright (C) zml and PermissionsEx contributors
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package ca.stellardrift.permissionsex.impl.util;
018
019import org.spongepowered.configurate.util.CheckedFunction;
020import org.spongepowered.configurate.util.CheckedSupplier;
021
022import java.util.Optional;
023import java.util.concurrent.CompletableFuture;
024import java.util.concurrent.Executor;
025
026public class Util {
027    /**
028     * Given an {@link Optional} of an unknown type, safely cast it to the expected type.
029     * If the optional is not of the required type, an empty optional is returned.
030     *
031     * @param input The input value
032     * @param clazz The class to cast to
033     * @param <T> The type of the class
034     * @return A casted or empty Optional
035     */
036    public static <T> Optional<T> castOptional(Optional<?> input, Class<T> clazz) {
037        return input.filter(clazz::isInstance).map(clazz::cast);
038    }
039
040    public static <T> CompletableFuture<T> failedFuture(Throwable error) {
041        CompletableFuture<T> ret = new CompletableFuture<>();
042        ret.completeExceptionally(error);
043        return ret;
044    }
045
046    private static final CompletableFuture<Object> EMPTY_FUTURE = new CompletableFuture<>();
047    static {
048        EMPTY_FUTURE.complete(null);
049    }
050
051    @SuppressWarnings({"unchecked", "rawtypes"})
052    public static <T> CompletableFuture<T> emptyFuture() {
053        return (CompletableFuture) EMPTY_FUTURE;
054    }
055
056    public static <I, T> CompletableFuture<T> failableFuture(I value, CheckedFunction<I, T, ?> func) {
057        return failableFuture(() -> func.apply(value));
058    }
059
060    public static <T> CompletableFuture<T> failableFuture(CheckedSupplier<T, ?> func) {
061        CompletableFuture<T> ret = new CompletableFuture<>();
062        try {
063            ret.complete(func.get());
064        } catch (Throwable e) {
065            ret.completeExceptionally(e);
066        }
067        return ret;
068    }
069
070    public static <T> CompletableFuture<T> asyncFailableFuture(CheckedSupplier<T, ?> supplier, Executor exec) {
071        CompletableFuture<T> ret = new CompletableFuture<>();
072        exec.execute(() -> {
073            try {
074                ret.complete(supplier.get());
075            } catch (Throwable e) {
076                ret.completeExceptionally(e);
077            }
078
079        });
080        return ret;
081    }
082}