package com.example.boidelov3.data;

/**
 * Wrapper pour représenter le résultat d'une opération qui peut échouer.
 * Remplace les exceptions par des valeurs de retour typées.
 *
 * @param <T> Le type de donnée en cas de succès
 * @param <E> Le type d'erreur en cas d'échec
 */
public class Result<T, E extends Exception> {
    private final T data;
    private final E error;

    private Result(T data, E error) {
        this.data = data;
        this.error = error;
    }

    /**
     * Crée un résultat réussi
     */
    public static <T, E extends Exception> Result<T, E> success(T data) {
        return new Result<>(data, null);
    }

    /**
     * Crée un résultat d'erreur
     */
    public static <T, E extends Exception> Result<T, E> failure(E error) {
        return new Result<>(null, error);
    }

    /**
     * @return true si l'opération a réussi
     */
    public boolean isSuccess() {
        return error == null;
    }

    /**
     * @return true si l'opération a échoué
     */
    public boolean isFailure() {
        return error != null;
    }

    /**
     * @return les données en cas de succès, null sinon
     */
    public T getData() {
        return data;
    }

    /**
     * @return l'erreur en cas d'échec, null sinon
     */
    public E getError() {
        return error;
    }

    /**
     * @return les données ou null si échec
     */
    public T getOrNull() {
        return data;
    }

    /**
     * @return les données ou une valeur par défaut
     */
    public T getOrElse(T defaultValue) {
        return isSuccess() ? data : defaultValue;
    }
}
