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

net.amygdalum.testrecorder.util.BiOptional Maven / Gradle / Ivy

The newest version!
package net.amygdalum.testrecorder.util;

import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;

public class BiOptional {

	private static final BiOptional EMPTY = new BiOptional<>();

	private T first;
	private T second;

	private BiOptional(T first, T second) {
		this.first = Objects.requireNonNull(first);
		this.second = Objects.requireNonNull(second);
	}

	private BiOptional(T first, boolean second) {
		this.first = Objects.requireNonNull(first);
	}

	private BiOptional(boolean first, T second) {
		this.second = Objects.requireNonNull(second);
	}

	private BiOptional() {
	}

	public static  BiOptional ofOptionals(Optional first, Optional second) {
		boolean firstPresent = first.isPresent();
		boolean secondPresent = second.isPresent();
		if (firstPresent && secondPresent) {
			return BiOptional.of(first.get(), second.get());
		}
		if (secondPresent) {
			return second(second.get());
		}
		if (firstPresent) {
			return first(first.get());
		}
		return empty();
	}

	public static  BiOptional ofNullable(T first, T second) {
		if (first == null && second == null) {
			return empty();
		}
		if (first == null) {
			return second(second);
		}
		if (second == null) {
			return first(first);
		}
		return BiOptional.of(first, second);
	}

	public static  BiOptional of(T first, T second) {
		return new BiOptional<>(first, second);
	}

	public static  BiOptional empty() {
		@SuppressWarnings("unchecked")
		BiOptional t = (BiOptional) EMPTY;
		return t;
	}

	public static  BiOptional first(T first) {
		return new BiOptional(first, false);
	}

	public static  BiOptional second(T second) {
		return new BiOptional(false, second);
	}

	public  BiOptional bimap(Function first, Function second) {
		return ofNullable(first.apply(this.first), second.apply(this.second));
	}

	public  BiOptional biflatmap(Function> first, Function> second) {
		return ofOptionals(first.apply(this.first), second.apply(this.second));
	}
	
	public BiOptional bifilter(Predicate first, Predicate second) {
		boolean firstOk = first.test(this.first);
		boolean secondOk = second.test(this.second);
		if (firstOk && secondOk) {
			return this;
		}
		if (firstOk) {
			return ofNullable(this.first, null);
		}
		if (secondOk) {
			return ofNullable(null, this.second);
		}
		return empty();
	}

	public  Optional map(BiFunction mapping) {
		if (first == null || second == null) {
			return Optional.empty();
		}
		return Optional.ofNullable(mapping.apply(first, second));
	}

	public  Optional map(BiFunction mapping, Function singleOnly) {
		if (first == null && second == null) {
			return Optional.empty();
		}
		if (first == null) {
			return Optional.ofNullable(singleOnly.apply(second));
		}
		if (second == null) {
			return Optional.ofNullable(singleOnly.apply(first));
		}
		return Optional.ofNullable(mapping.apply(first, second));
	}

	public  Optional map(BiFunction mapping, Function firstOnly, Function secondOnly) {
		if (first == null && second == null) {
			return Optional.empty();
		}
		if (first == null) {
			return Optional.ofNullable(secondOnly.apply(second));
		}
		if (second == null) {
			return Optional.ofNullable(firstOnly.apply(first));
		}
		return Optional.ofNullable(mapping.apply(first, second));
	}

}