package com.suse.salt.netapi.results;

import com.suse.salt.netapi.utils.Xor;

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

/**
 * Representation of call results for a single minion implemented as a wrapper around
 * {@link Xor}.
 *
 * @param <R> the type of the internal result
 */
public class Result<R> {

    private final Xor<SaltError, R> xor;

    public Result(Xor<SaltError, R> xor) {
        this.xor = xor;
    }

    public Optional<SaltError> error() {
        return xor.left();
    }

    public Optional<R> result() {
        return xor.right();
    }

    public <T> T fold(Function<? super SaltError, ? extends T> mapError,
            Function<? super R, ? extends T> mapResult) {
        return xor.fold(mapError, mapResult);
    }

    public void consume(Consumer<? super SaltError> consumerError,
            Consumer<? super R> consumerResult) {
        xor.consume(consumerError, consumerResult);
    }

    public <T> Result<T> map(Function<? super R, ? extends T> mapper) {
        return new Result<>(xor.map(mapper));
    }

    // FIXME: Redundant definition of type arguments needed for oraclejdk8
    @SuppressWarnings("unused")
    public <T> Result<T> flatMap(Function<? super R, Result<T>> mapper) {
        return xor.fold(
            e -> new Result<T>(Xor.left(e)),
            mapper
        );
    }

    public Xor<SaltError, R> toXor() {
        return xor;
    }
}

@@ -1454,11 +1454,491 @@
 r;%0A    %7D
+%0A%0A    @Override%0A    public boolean equals(Object obj) %7B%0A        if (this == obj) %7B%0A            return true;%0A        %7D%0A        if (obj == null %7C%7C getClass() != obj.getClass()) %7B%0A            return false;%0A        %7D%0A%0A        Result%3C?%3E other = (Result%3C?%3E) obj;%0A        return xor.equals(other.xor);%0A    %7D%0A%0A    @Override%0A    public String toString() %7B%0A        return xor.fold(%0A            error -%3E %22Error(%22 + error + %22)%22,%0A            result -%3E %22Result(%22 + result + %22)%22%0A        );%0A    %7D
 %0A%7D%0A

Implement equals() and toString()