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

xdean.jex.extra.collection.Either Maven / Gradle / Ivy

The newest version!
package xdean.jex.extra.collection;

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

import javax.annotation.concurrent.Immutable;

/**
 *
 * @author org.reactfx.util, XDean
 *
 * @param 
 * @param 
 */
@Immutable
public interface Either {

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

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

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

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

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

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

  boolean isLeft();

  boolean isRight();

  L getLeft();

  R getRight();

  L toLeft(Function f);

  R toRight(Function f);

  Optional asLeft();

  Optional asRight();

  Either ifLeft(Consumer f);

  Either ifRight(Consumer f);

  void exec(
      Consumer ifLeft,
      Consumer ifRight);

   Either mapLeft(
      Function f);

   Either mapRight(
      Function f);

   Either map(
      Function f,
      Function g);

   Either flatMap(
      Function> f,
      Function> g);

   Either flatMapLeft(
      Function> f);

   Either flatMapRight(
      Function> f);

   T unify(
      Function f,
      Function g);
}

class Left implements 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 Either ifLeft(Consumer f) {
    f.accept(value);
    return this;
  }

  @Override
  public Either ifRight(Consumer f) { /* do nothing */
    return this;
  }

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

  @Override
  public  Either mapLeft(Function f) {
    return new Left<>(f.apply(value));
  }

  @Override
  public  Either mapRight(Function f) {
    return new Left<>(value);
  }

  @Override
  public  Either map(
      Function f,
      Function g) {
    return new 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 new Left<>(value);
  }

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

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

  @Override
  public final 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 + ")";
  }
}

class Right implements 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 Either ifLeft(Consumer f) { /* do nothing */
    return this;
  }

  @Override
  public Either ifRight(Consumer f) {
    f.accept(value);
    return this;
  }

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

  @Override
  public  Either mapLeft(Function f) {
    return new Right<>(value);
  }

  @Override
  public  Either mapRight(Function f) {
    return new Right<>(f.apply(value));
  }

  @Override
  public  Either map(
      Function f,
      Function g) {
    return new Right<>(g.apply(value));
  }

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

  @Override
  public  Either flatMapLeft(
      Function> f) {
    return new 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 final int hashCode() {
    return Objects.hash(value);
  }

  @Override
  public final 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 + ")";
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy