예제 #1
0
        /// <summary>
        /// Invokes the specified <paramref name="continueWithFunction"/> function if <paramref name="serviceResponse"/>.IsLeft.
        /// Allows you to re-direct control flow with a new <typeparamref name="T" /> value.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serviceResponse">The service response.</param>
        /// <param name="continueWithFunction">The continue with function.</param>
        /// <returns>If errors exist, returns the instance of IServiceResponse{T} returned by <paramref name="continueWithFunction" />, else returns current instance.</returns>
        public static IServiceResponse <T> CatchAndContinue <T>(this IServiceResponse <T> serviceResponse, Func <Error, IServiceResponse <T> > continueWithFunction)
        {
            if (serviceResponse.IsLeft)
            {
                return(continueWithFunction.Invoke(serviceResponse.GetLeft()));
            }

            return(serviceResponse);
        }
예제 #2
0
        /// <summary>
        /// If <paramref name="serviceResponse"/>.IsLeft, returns a new <see cref="IServiceResponse{T2}" /> instance with the current
        /// <paramref name="serviceResponse"/>.Error. Otherwise, it binds the <paramref name="serviceResponse"/>.Data into the specified
        /// <paramref name="bindingFunction" />.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T2">The type of the next <see cref="IServiceResponse{T2}" /> to return.</typeparam>
        /// <param name="serviceResponse">The service response.</param>
        /// <param name="bindingFunction">The binding function.</param>
        /// <returns>Instance of <see cref="IServiceResponse{T2}" />.</returns>
        public static IServiceResponse <T2> Bind <T, T2>(this IServiceResponse <T> serviceResponse, Func <T, IServiceResponse <T2> > bindingFunction)
        {
            if (serviceResponse.IsLeft)
            {
                return(serviceResponse.CreateGenericErrorResponse <T, T2>(serviceResponse.GetLeft()));
            }

            return(bindingFunction.Invoke(serviceResponse.GetRight()));
        }
예제 #3
0
        /// <summary>
        /// Invokes the specified action if <paramref name="serviceResponse"/>.IsLeft.
        /// Returns the current instance.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serviceResponse">The service response.</param>
        /// <param name="action">The action to invoke.</param>
        /// <returns>The current <see cref="IServiceResponse{T}" /> instance.</returns>
        public static IServiceResponse <T> Catch <T>(this IServiceResponse <T> serviceResponse, Action <Error> action)
        {
            if (serviceResponse.IsLeft)
            {
                action.Invoke(serviceResponse.GetLeft());
            }

            return(serviceResponse);
        }
예제 #4
0
        /// <summary>
        /// Returns the error.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serviceResponse">The service response.</param>
        /// <returns>Error.</returns>
        /// <exception cref="System.InvalidOperationException">There is nothing to return from left of either - Error or Data.</exception>
        public static Error FromLeft <T>(this IServiceResponse <T> serviceResponse)
        {
            if (!serviceResponse.IsLeft)
            {
                throw new InvalidOperationException("Cannot return left of either when is right.");
            }

            return(serviceResponse.GetLeft());
        }
예제 #5
0
        /// <summary>
        /// Invokes the specified <paramref name="continueWithFunction"/> function if <paramref name="serviceResponse"/>.IsLeft.
        /// Allows you to re-direct control flow with a new <typeparamref name="T" /> value.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serviceResponse">The service response.</param>
        /// <param name="continueWithFunction">The continue with function.</param>
        /// <returns>If errors exist, returns the instance of IServiceResponse{T} returned by <paramref name="continueWithFunction" />, else returns current instance.</returns>
        public static IServiceResponse <T> CatchAndContinue <T>(this IServiceResponse <T> serviceResponse, Func <Error, T> continueWithFunction)
        {
            if (serviceResponse.IsLeft)
            {
                T result = continueWithFunction.Invoke(serviceResponse.GetLeft());

                return(new DataResponse <T>(result));
            }

            return(serviceResponse);
        }
예제 #6
0
        /// <summary>
        /// If <paramref name="serviceResponse"/>.IsLeft, returns a new <see cref="IServiceResponse{T2}" /> instance with the current
        /// <paramref name="serviceResponse"/>.Error. Otherwise, it binds the <paramref name="serviceResponse"/>.Data into
        /// the specified <paramref name="mappingFunction" />.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T2">The type of the next <see cref="IServiceResponse{T2}" /> to return.</typeparam>
        /// <param name="serviceResponse">The service response.</param>
        /// <param name="mappingFunction">The mapping function.</param>
        /// <returns>Instance of <see cref="IServiceResponse{T2}" />.</returns>
        public static IServiceResponse <T2> Fmap <T, T2>(this IServiceResponse <T> serviceResponse, Func <T, T2> mappingFunction)
        {
            if (serviceResponse.IsLeft)
            {
                return(serviceResponse.CreateGenericErrorResponse <T, T2>(serviceResponse.GetLeft()));
            }

            T2 result = mappingFunction.Invoke(serviceResponse.GetRight());

            return(serviceResponse.CreateGenericDataResponse(result));
        }
        /// <summary>
        /// Invokes the specified <paramref name="continueWithFunction"/> function if <see cref="IServiceResponse{T}.IsLeft"/>.
        /// Allows you to re-direct control flow with a new <typeparamref name="T" /> value.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serviceResponse">The service response.</param>
        /// <param name="continueWithFunction">The continue with function.</param>
        /// <returns>If <paramref name="serviceResponse"/>.IsLeft, then the instance of <see cref="IServiceResponse{T}" />
        /// returned by <paramref name="continueWithFunction" />, else returns current <paramref name="serviceResponse"/>.</returns>
        public static Task <IServiceResponse <T> > CatchAndContinueAsync <T>(
            this IServiceResponse <T> serviceResponse,
            Func <Error, Task <IServiceResponse <T> > > continueWithFunction)
        {
            if (serviceResponse.IsLeft)
            {
                return(continueWithFunction.Invoke(serviceResponse.GetLeft()));
            }

            return(Task.FromResult(serviceResponse));
        }
        /// <summary>
        /// Invokes the specified <paramref name="continueWithFunction"/> function if <see cref="IServiceResponse{T}.IsLeft"/>.
        /// Allows you to re-direct control flow with a new <typeparamref name="T" /> value.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serviceResponse">The service response.</param>
        /// <param name="continueWithFunction">The continue with function.</param>
        /// <returns>If <paramref name="serviceResponse"/>.IsLeft, then the instance of <see cref="IServiceResponse{T}" />
        /// returned by <paramref name="continueWithFunction" />, else returns current <paramref name="serviceResponse"/>.</returns>
        public static Task <IServiceResponse <T> > CatchAndContinueAsync <T>(
            this IServiceResponse <T> serviceResponse,
            Func <Error, T> continueWithFunction)
        {
            var tcs = new TaskCompletionSource <IServiceResponse <T> >();

            if (serviceResponse.IsLeft)
            {
                T result = continueWithFunction.Invoke(serviceResponse.GetLeft());

                tcs.SetResult(new DataResponse <T>(result));
            }
            else
            {
                tcs.SetResult(serviceResponse);
            }

            return(tcs.Task);
        }
        /// <summary>
        /// Invokes the specified function if <see cref="IServiceResponse{T}.IsLeft"/>. Returns the current <paramref name="serviceResponse"/>
        /// unless the <paramref name="catchFunc"/> returns a faulted task. <see cref="Task.IsFaulted"/>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serviceResponse">The service response.</param>
        /// <param name="catchFunc">Async function to invoke.</param>
        /// <returns>The current <paramref name="serviceResponse"/> unless the <paramref name="catchFunc"/> returns a faulted task.</returns>
        public static Task <IServiceResponse <T> > CatchAsync <T>(
            this IServiceResponse <T> serviceResponse,
            Func <Error, Task> catchFunc)
        {
            if (serviceResponse.IsLeft)
            {
                return(catchFunc.Invoke(serviceResponse.GetLeft())
                       .ContinueWith(task =>
                {
                    if (task.IsFaulted)
                    {
                        return serviceResponse.CreateGenericErrorResponse(task.Exception.ToError());
                    }

                    return serviceResponse;
                },
                                     CancellationToken.None,
                                     TaskContinuationOptions.ExecuteSynchronously,
                                     TaskScheduler.Default));
            }

            return(Task.FromResult(serviceResponse));
        }
        public static async Task <IServiceResponse <IEnumerable <T2> > > BindManyAsync <T, T2>(
            this IServiceResponse <IEnumerable <T> > serviceResponse,
            Func <T, Task <IServiceResponse <T2> > > bindFunc)
        {
            if (serviceResponse.IsLeft)
            {
                return(serviceResponse.CreateGenericErrorResponse <IEnumerable <T>, IEnumerable <T2> >(serviceResponse.GetLeft()));
            }

            var result = new List <T2>();

            foreach (var element in serviceResponse.GetRight())
            {
                var elementResponse = await bindFunc(element);

                if (elementResponse.IsLeft)
                {
                    return(serviceResponse.CreateGenericErrorResponse <IEnumerable <T>, IEnumerable <T2> >(elementResponse.GetLeft()));
                }

                result.Add(elementResponse.GetRight());
            }

            return(serviceResponse.CreateGenericDataResponse(result));
        }
        /// <summary>
        /// If <seealso cref="IServiceResponse{T}.IsLeft" />, returns a new <see cref="IServiceResponse{T2}" /> instance with the current
        /// <seealso cref="IServiceResponse{T}.Error" />. Else, binds the <seealso cref="IServiceResponse{T}.Data" /> into the
        /// specified <paramref name="bindFunc" />.
        /// </summary>
        /// <typeparam name="T">The type of the current <see cref="IServiceResponse{T}"/>.</typeparam>
        /// <typeparam name="T2">The type of the next <see cref="IServiceResponse{T2}" /> to return.</typeparam>
        /// <param name="serviceResponse">The service response.</param>
        /// <param name="bindFunc">The binding function.</param>
        /// <returns>Instance of <see cref="IServiceResponse{T2}" />.</returns>
        public static Task <IServiceResponse <T2> > BindAsync <T, T2>(
            this IServiceResponse <T> serviceResponse,
            Func <T, Task <IServiceResponse <T2> > > bindFunc)
        {
            if (serviceResponse.IsLeft)
            {
                return(Task.FromResult(serviceResponse.CreateGenericErrorResponse <T, T2>(serviceResponse.GetLeft())));
            }

            return(bindFunc(serviceResponse.GetRight()));
        }