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

io.activej.common.collection.Either Maven / Gradle / Ivy

There is a newer version: 4.3-r8
Show newest version
/*
 * Copyright (C) 2020 ActiveJ LLC.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.activej.common.collection;

import io.activej.common.recycle.Recyclers;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.function.*;

import static io.activej.common.Checks.checkState;

public final class Either {
	static {
		Recyclers.register(Either.class, either -> {
			Recyclers.recycle(either.left);
			Recyclers.recycle(either.right);
		});
	}

	@Nullable
	private final L left;

	@Nullable
	private final R right;

	private final boolean isRight; // so that this either supports nulls

	private Either(@Nullable L left, @Nullable R right, boolean isRight) {
		this.left = left;
		this.right = right;
		this.isRight = isRight;
	}

	public static  Either left(@Nullable L left) {
		return new Either<>(left, null, false);
	}

	public static  Either right(@Nullable R right) {
		return new Either<>(null, right, true);
	}

	@Contract(pure = true)
	public boolean isLeft() {
		return !isRight;
	}

	@Contract(pure = true)
	public boolean isRight() {
		return isRight;
	}

	@Contract(pure = true)
	public L getLeft() {
		checkState(isLeft());
		return left;
	}

	@Contract(pure = true)
	public R getRight() {
		checkState(isRight());
		return right;
	}

	@Contract(pure = true)
	@Nullable
	public L getLeftOrNull() {
		return left;
	}

	@Contract(pure = true)
	@Nullable
	public R getRightOrNull() {
		return right;
	}

	@Contract(pure = true)
	public L getLeftOr(@Nullable L defaultValue) {
		return isLeft() ? left : defaultValue;
	}

	@Contract(pure = true)
	public R getRightOr(@Nullable R defaultValue) {
		return isRight() ? right : defaultValue;
	}

	@Contract(pure = true)
	public L getLeftOrSupply(@NotNull Supplier defaultValueSupplier) {
		return isLeft() ? left : defaultValueSupplier.get();
	}

	@Contract(pure = true)
	public R getRightOrSupply(@NotNull Supplier defaultValueSupplier) {
		return isRight() ? right : defaultValueSupplier.get();
	}

	@Contract(pure = true)
	@NotNull
	public Either ifLeft(@NotNull Consumer leftConsumer) {
		if (isLeft()) {
			leftConsumer.accept(left);
		}
		return this;
	}

	@Contract(pure = true)
	@NotNull
	public Either ifRight(@NotNull Consumer rightConsumer) {
		if (isRight()) {
			rightConsumer.accept(right);
		}
		return this;
	}

	@Contract(pure = true)
	@NotNull
	public Either consume(@NotNull BiConsumer consumer) {
		consumer.accept(left, right);
		return this;
	}

	@Contract(pure = true)
	@NotNull
	public Either consume(@NotNull Consumer leftConsumer, @NotNull Consumer rightConsumer) {
		if (isLeft()) {
			leftConsumer.accept(left);
		} else {
			rightConsumer.accept(right);
		}
		return this;
	}

	@Contract(pure = true)
	public  U reduce(@NotNull Function leftFn, @NotNull Function rightFn) {
		return isLeft() ? leftFn.apply(left) : rightFn.apply(right);
	}

	@Contract(pure = true)
	public  U reduce(@NotNull BiFunction fn) {
		return fn.apply(left, right);
	}

	@Contract(pure = true)
	@NotNull
	public Either swap() {
		return new Either<>(right, left, !isRight);
	}

	@SuppressWarnings("unchecked")
	@Contract(pure = true)
	@NotNull
	public  Either mapLeft(@NotNull Function fn) {
		return isLeft() ?
				new Either<>(fn.apply(left), null, false) :
				(Either) this;
	}

	@SuppressWarnings("unchecked")
	@Contract(pure = true)
	@NotNull
	public  Either mapRight(@NotNull Function fn) {
		return isRight() ?
				new Either<>(null, fn.apply(right), true) :
				(Either) this;
	}

	@SuppressWarnings("unchecked")
	@Contract(pure = true)
	@NotNull
	public  Either flatMapLeft(@NotNull Function> fn) {
		return isLeft() ?
				fn.apply(left) :
				(Either) this;
	}

	@SuppressWarnings("unchecked")
	@Contract(pure = true)
	@NotNull
	public  Either flatMapRight(@NotNull Function> fn) {
		return isRight() ?
				fn.apply(right) :
				(Either) this;
	}
}