All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.smallibs.data.Try Maven / Gradle / Ivy

There is a newer version: 0.11.0
Show newest version
/*
 * HPAS
 * https://github.com/d-plaindoux/hpas
 *
 * Copyright (c) 2016-2017 Didier Plaindoux
 * Licensed under the LGPL2 license.
 */

package org.smallibs.data;

import org.smallibs.control.Filter;
import org.smallibs.exception.FilterException;
import org.smallibs.type.HK;

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

public interface Try extends Filter>, HK> {

    static  Try success(T value) {
        if (Throwable.class.isInstance(value)) {
            return new Failure<>(Throwable.class.cast(value));
        }

        return new Success<>(value);
    }

    static  Try failure(Throwable value) {
        return new Failure<>(value);
    }

    @Override
    default Try filter(Predicate predicate) {
        return this.flatmap(t -> predicate.test(t) ? this : Try.failure(new FilterException()));
    }

    @Override
    default  R accept(Function>, R> f) {
        return f.apply(this);
    }

    @Override
    default Try self() {
        return this;
    }

    default  Try map(Function mapper) {
        return this.flatmap(t -> success(mapper.apply(t)));
    }

    default  B fold(Function success, Function failure) {
        return this.map(success).recoverWith(failure);
    }

    default T recoverWith(T t) {
        return this.recoverWith(x -> t);
    }

    default  T orElseThrow(Supplier exceptionSupplier) throws X {
        return this.orElseThrow(x -> exceptionSupplier.get());
    }

    default T orElseThrow() throws Throwable {
        return this.orElseThrow(x -> x);
    }

    default boolean isSuccess() {
        return this.fold(t -> true, f -> false);
    }

    T recoverWith(Function t);

     T orElseThrow(Function exceptionSupplier) throws X;

     Try flatmap(Function> mapper);

    Try onSuccess(Consumer onSuccess);

    Try onFailure(Consumer onFailure);

    /**
     * Success implementation
     */
    final class Success implements Try {
        private final T value;

        private Success(T value) {
            this.value = value;
        }

        @Override
        public  Try flatmap(Function> mapper) {
            return mapper.apply(this.value);
        }

        @Override
        public Try onSuccess(Consumer onSuccess) {
            onSuccess.accept(this.value);
            return this;
        }

        @Override
        public Try onFailure(Consumer onFailure) {
            return this;
        }

        @Override
        public  T orElseThrow(Function exceptionSupplier) throws X {
            return this.value;
        }

        @Override
        public T recoverWith(Function t) {
            return this.value;
        }
    }

    /**
     * Failure implementation
     */
    final class Failure implements Try {
        private final Throwable value;

        private Failure(Throwable value) {
            this.value = value;
        }

        @Override
        public  Try flatmap(Function> mapper) {
            return Try.failure(this.value);
        }

        @Override
        public Try onSuccess(Consumer onSuccess) {
            return this;
        }

        @Override
        public Try onFailure(Consumer onFailure) {
            onFailure.accept(this.value);
            return this;
        }

        @Override
        public  T orElseThrow(Function exceptionSupplier) throws X {
            throw exceptionSupplier.apply(this.value);
        }

        @Override
        public T recoverWith(Function t) {
            return t.apply(this.value);
        }

    }

}