/// <summary>
 /// Ensures that there is a value. Throws if there is not.
 /// </summary>
 /// <param name="result">The result.</param>
 /// <exception cref="ErrorException">The exception containing the error.</exception>
 public static void EnsureSuccess(this IResult result)
 {
     if (result.IsSuccess)
     {
         return;
     }
     else
     {
         IFail fail = result.AsFail();
         throw new ErrorException(fail.Error, fail.Error.Message ?? string.Empty);
     }
 }
        /// <summary>
        /// Performs a mapping depending on the type of the stored value.
        /// </summary>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <typeparam name="TResult">The resultant type.</typeparam>
        /// <param name="result">The result.</param>
        /// <param name="onSuccess">The mapping for a value.</param>
        /// <param name="onError">The mapping for an error.</param>
        /// <returns>The mapped result.</returns>
        public static TResult Match <TValue, TResult>(this IResult result, Func <TValue?, TResult> onSuccess, Func <Error, TResult> onError)
        {
            if (result.IsSuccess && onSuccess != null)
            {
                return(onSuccess(result.AsSuccess <TValue>().Value));
            }

            if (result.IsSuccess == false && onError != null)
            {
                return(onError(result.AsFail().Error));
            }

            throw new InvalidOperationException();
        }
        /// <summary>
        /// Executes one of the actions depending on the type of the stored value.
        /// </summary>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="result">The result.</param>
        /// <param name="onSuccess">The action to execute for a value.</param>
        /// <param name="onError">The action to execute for an error.</param>
        public static void Switch <TValue>(this IResult result, Action <TValue?> onSuccess, Action <Error> onError)
        {
            if (result.IsSuccess && onSuccess != null)
            {
                onSuccess(result.AsSuccess <TValue>().Value);
                return;
            }

            if (result.IsSuccess == false && onError != null)
            {
                onError(result.AsFail().Error);
                return;
            }

            throw new InvalidOperationException();
        }