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));
        }
Пример #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>
        /// If <seealso cref="IServiceResponse{T}.Error" /> is not null, 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="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.Error != null)
            {
                return(serviceResponse.CreateGenericErrorResponse <T, T2>(serviceResponse.Error));
            }

            return(bindingFunction.Invoke(serviceResponse.Data));
        }
        /// <summary>
        /// Invokes the specified action if <see cref="IServiceResponse{T}.Error" /> is null.
        /// Returns the current <see cref="IServiceResponse{T}" /> instance unless the task
        /// from <paramref name="letFunc"/> <see cref="Task.IsFaulted"/>.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serviceResponse">The service response.</param>
        /// <param name="letFunc">The let function.</param>
        /// <returns>Task&lt;IServiceResponse&lt;T&gt;&gt;.</returns>
        public static Task <IServiceResponse <T> > LetAsync <T>(
            this IServiceResponse <T> serviceResponse,
            Func <T, Task> letFunc)
        {
            if (serviceResponse.Error != null)
            {
                return(Task.FromResult(serviceResponse.CreateGenericErrorResponse(serviceResponse.Error)));
            }

            return(letFunc(serviceResponse.Data)
                   .ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    return serviceResponse.CreateGenericErrorResponse(task.Exception.ToError());
                }

                return serviceResponse.CreateGenericDataResponse <T>(serviceResponse.Data);
            }));
        }
Пример #5
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));
        }
Пример #6
0
        /// <summary>
        /// If <seealso cref="IServiceResponse{T}.Error" /> is not null, 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="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.Error != null)
            {
                return(serviceResponse.CreateGenericErrorResponse <T, T2>(serviceResponse.Error));
            }

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

            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()));
        }
        /// <summary>
        /// If <seealso cref="IServiceResponse{T}.Error" /> is not null, 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"></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.Error != null)
            {
                var tcs = new TaskCompletionSource <IServiceResponse <T2> >();
                tcs.SetResult(serviceResponse.CreateGenericErrorResponse <T, T2>(serviceResponse.Error));

                return(tcs.Task);
            }

            return(bindFunc(serviceResponse.Data));
        }
        /// <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));
        }