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

org.reactfx.util.Either Maven / Gradle / Ivy

There is a newer version: 2.0-M5
Show newest version
package org.reactfx.util;

import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;

public abstract class Either {

    private static class Left extends Either {
        private final L value;

        public Left(L value) { this.value = value; }

        @Override
        public boolean isLeft() { return true; }

        @Override
        public boolean isRight() { return false; }

        @Override
        public L getLeft() { return value; }

        @Override
        public R getRight() { throw new NoSuchElementException(); }

        @Override
        public L toLeft(Function f) {
            return value;
        }

        @Override
        public R toRight(Function f) {
            return f.apply(value);
        }

        @Override
        public Optional asLeft() { return Optional.of(value); }

        @Override
        public Optional asRight() { return Optional.empty(); }

        @Override
        public void ifLeft(Consumer f) { f.accept(value); }

        @Override
        public void ifRight(Consumer f) { /* do nothing */ }

        @Override
        public void exec(
                Consumer ifLeft,
                Consumer ifRight) {
            ifLeft.accept(value);
        }

        @Override
        public  Either mapLeft(Function f) {
            return left(f.apply(value));
        }

        @Override
        public  Either mapRight(Function f) {
            return left(value);
        }

        @Override
        public  Either map(
                Function f,
                Function g) {
            return left(f.apply(value));
        }

        @Override
        public  Either flatMap(
                Function> f,
                Function> g) {
            return f.apply(value);
        }

        @Override
        public  Either flatMapLeft(
                Function> f) {
            return f.apply(value);
        }

        @Override
        public  Either flatMapRight(
                Function> f) {
            return left(value);
        }

        @Override
        public  T unify(
                Function f,
                Function g) {
            return f.apply(value);
        }

        @Override
        public int hashCode() {
            return Objects.hash(value);
        }

        @Override
        public boolean equals(Object other) {
            if(other instanceof Left) {
                Left that = (Left) other;
                return Objects.equals(this.value, that.value);
            } else {
                return false;
            }
        }

        @Override
        public String toString() {
            return "left(" + value + ")";
        }
    }

    private static class Right extends Either {
        private final R value;

        public Right(R value) { this.value = value; }

        @Override
        public boolean isLeft() { return false; }

        @Override
        public boolean isRight() { return true; }

        @Override
        public L getLeft() { throw new NoSuchElementException(); }

        @Override
        public R getRight() { return value; }

        @Override
        public L toLeft(Function f) {
            return f.apply(value);
        }

        @Override
        public R toRight(Function f) {
            return value;
        }

        @Override
        public Optional asLeft() { return Optional.empty(); }

        @Override
        public Optional asRight() { return Optional.of(value); }

        @Override
        public void ifLeft(Consumer f) { /* do nothing */ }

        @Override
        public void ifRight(Consumer f) { f.accept(value); }

        @Override
        public void exec(
                Consumer ifLeft,
                Consumer ifRight) {
            ifRight.accept(value);
        }

        @Override
        public  Either mapLeft(Function f) {
            return right(value);
        }

        @Override
        public  Either mapRight(Function f) {
            return right(f.apply(value));
        }

        @Override
        public  Either map(
                Function f,
                Function g) {
            return right(g.apply(value));
        }

        @Override
        public  Either flatMap(
                Function> f,
                Function> g) {
            return g.apply(value);
        }

        @Override
        public  Either flatMapLeft(
                Function> f) {
            return right(value);
        }

        @Override
        public  Either flatMapRight(
                Function> f) {
            return f.apply(value);
        }

        @Override
        public  T unify(
                Function f,
                Function g) {
            return g.apply(value);
        }

        @Override
        public int hashCode() {
            return Objects.hash(value);
        }

        @Override
        public boolean equals(Object other) {
            if(other instanceof Right) {
                Right that = (Right) other;
                return Objects.equals(this.value, that.value);
            } else {
                return false;
            }
        }

        @Override
        public String toString() {
            return "right(" + value + ")";
        }
    }

    public static  Either left(L l) {
        return new Left<>(l);
    }

    public static  Either right(R r) {
        return new Right<>(r);
    }

    public static  Either leftOrNull(Optional l) {
        return leftOrDefault(l, null);
    }

    public static  Either rightOrNull(Optional r) {
        return rightOrDefault(r, null);
    }

    public static  Either leftOrDefault(Optional l, R r) {
        return l.isPresent() ? left(l.get()) : right(r);
    }

    public static  Either rightOrDefault(Optional r, L l) {
        return r.isPresent() ? right(r.get()) : left(l);
    }

    // private constructor to prevent subclassing
    private Either() {}

    public abstract boolean isLeft();
    public abstract boolean isRight();
    public abstract L getLeft();
    public abstract R getRight();
    public abstract L toLeft(Function f);
    public abstract R toRight(Function f);
    public abstract Optional asLeft();
    public abstract Optional asRight();
    public abstract void ifLeft(Consumer f);
    public abstract void ifRight(Consumer f);
    public abstract void exec(
            Consumer ifLeft,
            Consumer ifRight);
    public abstract  Either mapLeft(
            Function f);
    public abstract  Either mapRight(
            Function f);
    public abstract  Either map(
            Function f,
            Function g);
    public abstract  Either flatMap(
            Function> f,
            Function> g);
    public abstract  Either flatMapLeft(
            Function> f);
    public abstract  Either flatMapRight(
            Function> f);
    public abstract  T unify(
            Function f,
            Function g);
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy