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

software.amazon.awssdk.utils.Either Maven / Gradle / Ivy

There is a newer version: 2.29.16
Show newest version
/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.utils;

import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import software.amazon.awssdk.annotations.SdkProtectedApi;

/**
 * Represents a value that can be one of two types.
 *
 * @param  Left type
 * @param  Right type
 */
@SdkProtectedApi
public final class Either {

    private final Optional left;
    private final Optional right;

    private Either(Optional l, Optional r) {
        left = l;
        right = r;
    }

    /**
     * Maps the Either to a type and returns the resolved value (which may be from the left or the right value).
     *
     * @param lFunc Function that maps the left value if present.
     * @param rFunc Function that maps the right value if present.
     * @param    Type that both the left and right should be mapped to.
     * @return Mapped value from either lFunc or rFunc depending on which value is present.
     */
    public  T map(
            Function lFunc,
            Function rFunc) {
        return left.map(lFunc).orElseGet(() -> right.map(rFunc).get());
    }

    /**
     * Map the left most value and return a new Either reflecting the new types.
     *
     * @param lFunc Function that maps the left value if present.
     * @param    New type of left value.
     * @return New Either bound to the new left type and the same right type.
     */
    public  Either mapLeft(Function lFunc) {
        return new Either<>(left.map(lFunc), right);
    }

    /**
     * Map the right most value and return a new Either reflecting the new types.
     *
     * @param rFunc Function that maps the right value if present.
     * @param    New type of right value.
     * @return New Either bound to the same left type and the new right type.
     */
    public  Either mapRight(Function rFunc) {
        return new Either<>(left, right.map(rFunc));
    }

    /**
     * Apply the consumers to the left or the right value depending on which is present.
     *
     * @param lFunc Consumer of left value, invoked if left value is present.
     * @param rFunc Consumer of right value, invoked if right value is present.
     */
    public void apply(Consumer lFunc, Consumer rFunc) {
        left.ifPresent(lFunc);
        right.ifPresent(rFunc);
    }

    /**
     * Create a new Either with the left type.
     *
     * @param value Left value
     * @param    Left type
     * @param    Right type
     */
    public static  Either left(L value) {
        return new Either<>(Optional.of(value), Optional.empty());
    }

    /**
     * Create a new Either with the right type.
     *
     * @param value Right value
     * @param    Left type
     * @param    Right type
     */
    public static  Either right(R value) {
        return new Either<>(Optional.empty(), Optional.of(value));
    }

    /**
     * @return the left value
     */
    public Optional left() {
        return left;
    }

    /**
     * @return the right value
     */
    public Optional right() {
        return right;
    }

    /**
     * Create a new {@code Optional} from two possibly null values.
     *
     * If both values are null, {@link Optional#empty()} is returned. Only one of the left or right values
     * is allowed to be non-null, otherwise an {@link IllegalArgumentException} is thrown.
     * @param left The left value (possibly null)
     * @param right The right value (possibly null)
     * @param  Left type
     * @param  Right type
     * @return an Optional Either representing one of the two values or empty if both are null
     */
    public static  Optional> fromNullable(L left, R right) {
        if (left != null && right == null) {
            return Optional.of(left(left));
        }
        if (left == null && right != null) {
            return Optional.of(right(right));
        }
        if (left == null && right == null) {
            return Optional.empty();
        }
        throw new IllegalArgumentException(String.format("Only one of either left or right should be non-null. "
                                                         + "Got (left: %s, right: %s)", left, right));
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Either)) {
            return false;
        }

        Either either = (Either) o;

        return left.equals(either.left) && right.equals(either.right);
    }

    @Override
    public int hashCode() {
        return 31 * left.hashCode() + right.hashCode();
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy