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

org.unlaxer.util.Try Maven / Gradle / Ivy

The newest version!
package org.unlaxer.util;

import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;

import org.unlaxer.util.function.Unchecked.ThrowingSupplier;

public class Try extends Either {

  public final Optional throwable;

  public final Optional> throwableConsumer;

  public Try(Throwable left, R right) {
    super(left, right);
    throwable = super.left;
    throwableConsumer = Optional.empty();
  }

  public Try(Throwable left, R right, Consumer throwableConsumer) {
    super(left, right);
    throwable = super.left;
    this.throwableConsumer = Optional.of(throwableConsumer);
  }

//  public Try(Throwable left, Supplier right) {
//    super(left, right);
//    throwable = super.left;
//    throwableConsumer = Optional.empty();
//  }


  /**
   * right value is {@link Supplier#get()} 1 times.
   * 
   * @param supplier
   * @return Try
   */
  public static  Try resultOf(ThrowingSupplier supplier) {
    try {
      R r = supplier.get();
      return ofNullable(r);
    } catch (Throwable e) {
      return immediatesOf(e);
    }
  }

  /**
   * right value is {@link Supplier#get()} 1 times.
   * 
   * @param supplier
   * @return Try
   */
  public static  Try resultOf(ThrowingSupplier supplier,
      Consumer throwableConsumer) {
    try {
      R r = supplier.get();
      return ofNullable(r);
    } catch (Throwable e) {
      throwableConsumer.accept(e);
      return immediatesOf(e);
    }
  }

//  /**
//   * right value is supplier. right value evaluates by call {@link Try#right()}
//   * 
//   * @param supplier
//   * @return Try
//   */
//  public static  Try supplierOf(Supplier supplier) {
//    try {
//      return immediatesOf(supplier);
//    } catch (Throwable e) {
//      return immediatesOf(e);
//    }
//  }


  public static  Try immediatesOf(R right) {
    if (right == null) {
      throw new IllegalArgumentException("must be not null");
    }
    return new Try(null, right);
  }

  public static  Try ofNullable(R right) {
    return new Try(null, right);
  }

  public static  Try ofNullable(R right, Consumer throwableConsuer) {
    return new Try(null, right, throwableConsuer);
  }

//  public static  Try immediatesOf(Supplier right) {
//    if (right == null) {
//      throw new IllegalArgumentException("must be not null");
//    }
//    return new Try(null, right);
//  }
//
//  public static  Try ofNullable(Supplier right) {
//    return new Try(null, right);
//  }


  public static  Try immediatesOf(Throwable left) {
    if (left == null) {
      throw new IllegalArgumentException("must be not null");
    }
    return new Try(left, (R) null);
  }

//  public static void require(Try... required) throws ContentNotFoundException {
//    List failed = Arrays.stream(required).filter(t -> !t.isPresent())
//        .map(t -> t.throwable.orElseThrow()).collect(Collectors.toList());
//    if (!failed.isEmpty()) {
//      StringBuilder sb = new StringBuilder("required, but failed:");
//      failed.stream().filter(t -> StringUtils.isNotEmpty(t.getMessage()))
//          .forEach(e -> sb.append("\n").append(e.getMessage()));
//      throw new ContentNotFoundException(sb.toString(), failed.get(0));
//    }
//  }

  public static  Try> zip(Try first, Try second) {
    if (first.right().isPresent() && second.right().isPresent()) {
      return Try.immediatesOf(new Tuple2<>(first.get(), second.get()));
    } else if (first.throwable.isPresent()) {
      return Try.immediatesOf(first.throwable.get());
    } else {
      return Try.immediatesOf(second.throwable.orElseThrow());
    }
  }
  
  public Optional right(){
    return right;
  }
  
  public void throwIfMatch(Function throwableMapper) {
    throwable.map(throwableMapper).ifPresent(x -> {
      throw x;
    });
  }

  public void throwIfMatch() {
    throwable.map(RuntimeException::new).ifPresent(x -> {
      throw x;
    });
  }

  public Try fallback(ThrowingSupplier supplier) {
    if (left.isPresent()) {
      return resultOf(supplier);
    }
    return this;
  }

  public Optional filter(Predicate arg0) {
    return right().filter(arg0);
  }

  public  Optional flatMapOptional(
      Function> arg0) {
    return right().flatMap(arg0);
  }

  public R get() {
    return right().orElseThrow(() -> new RuntimeException(throwable.get()));
  }


  public void ifPresent(Consumer arg0) {
    right().ifPresent(arg0);
  }

  public void ifPresentOrElse(Consumer arg0, Runnable arg1) {
    right().ifPresentOrElse(arg0, arg1);
  }

  public boolean fold(Consumer leftConsumer, Consumer rightConsumer) {
    if (isPresent()) {
      rightConsumer.accept(right.get());
//    } else if (rightSupplier.isPresent()) {
//      R r;
//      try {
//        r = rightSupplier.get().get();
//      } catch (Throwable t) {
//        leftConsumer.accept(t);
//        return false;
//      }
//      rightConsumer.accept(r);
    } else if (throwable.isPresent()) {
      leftConsumer.accept(left.get());
      return false;
    }
    return true;
  }

  public boolean isPresent() {
    return right().isPresent();
  }

  public  Optional mapOptional(Function arg0) {
    return right().map(arg0);
  }

  public Optional or(Supplier> arg0) {
    return right().or(arg0);
  }

  public R orElse(R arg0) {
    return right().orElse(arg0);
  }

  public R orElseGet(Supplier arg0) {
    return right().orElseGet(arg0);
  }

  public R orElseThrow() {
    return right().orElseThrow();
  }

  public  R orElseThrow(Supplier arg0) throws X {
    return right().orElseThrow(arg0);
  }

  public Stream stream() {
    return right().stream();
  }

  public  Try map(Function mapping) {
    return new Try(left.orElse(null), right().map(mapping).orElse(null));
  }

  public  Try flatMap(Function> mapping) {
    return right().map(mapping).orElse(immediatesOf(left.orElseThrow()));
  }

}