Summary

Class:AsyncEnumeration.Implementation.Enumerable.AsyncEnumerable
Assembly:AsyncEnumeration.Implementation.Enumerable
File(s):/repo-dir/contents/Source/Code/AsyncEnumeration.Implementation.Enumerable/Generation.cs
Covered lines:103
Uncovered lines:0
Coverable lines:103
Total lines:345
Line coverage:100%
Branch coverage:80%
Tag:7d9974899246b95481b7aa9cd3a1462ae2a67c91

Coverage History

Metrics

MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage
Repeat(...)201%1%
Repeat(...)201%1%
Repeat(...)201%0.5%
Repeat(...)201%0.5%
Repeat(...)201%0.5%
Repeat(...)201%0.5%
Range(...)401%1%
Range(...)401%1%
Neverending(...)101%0%
Neverending(...)101%0%
Neverending(...)101%0%

File(s)

/repo-dir/contents/Source/Code/AsyncEnumeration.Implementation.Enumerable/Generation.cs

#LineLine coverage
 1/*
 2 * Copyright 2018 Stanislav Muhametsin. All rights Reserved.
 3 *
 4 * Licensed  under the  Apache License,  Version 2.0  (the "License");
 5 * you may not use  this file  except in  compliance with the License.
 6 * You may obtain a copy of the License at
 7 *
 8 *   http://www.apache.org/licenses/LICENSE-2.0
 9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed  under the  License is distributed on an "AS IS" BASIS,
 12 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
 13 * implied.
 14 *
 15 * See the License for the specific language governing permissions and
 16 * limitations under the License.
 17 */
 18using AsyncEnumeration.Abstractions;
 19using System;
 20using System.Collections.Generic;
 21using System.Text;
 22using System.Threading;
 23using System.Threading.Tasks;
 24
 25namespace AsyncEnumeration.Implementation.Enumerable
 26{
 27   /// <summary>
 28   /// This class provides some general ways to generate instances of <see cref="IAsyncEnumerable{T}"/>, similar to how 
 29   /// </summary>
 30   public static class AsyncEnumerable
 31   {
 32
 33      /// <summary>
 34      /// Returns <see cref="IAsyncEnumerable{T}"/> that will return the given item specified amount of times.
 35      /// </summary>
 36      /// <typeparam name="T">The type of item to repeat.</typeparam>
 37      /// <param name="item">The item to repeat.</param>
 38      /// <param name="count">Amount of times to repeat the <paramref name="item"/>.</param>
 39      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 40      /// <returns>An empty <see cref="IAsyncEnumerable{T}"/> if <paramref name="count"/> is <c>0</c> or less; otherwise
 41      /// <seealso cref="System.Linq.Enumerable.Repeat{TResult}(TResult, Int32)"/>
 42      /// <seealso cref="Repeat{T}(T, Int64, IAsyncProvider)"/>
 43      public static IAsyncEnumerable<T> Repeat<T>(
 44         T item,
 45         Int32 count,
 46         IAsyncProvider asyncProvider
 47         )
 48      {
 649         return count <= 0 ?
 650            EmptyAsync<T>.Enumerable :
 2351            Neverending( () => item, asyncProvider ).Take( count );
 52      }
 53
 54      /// <summary>
 55      /// Returns <see cref="IAsyncEnumerable{T}"/> that will return the given item specified amount of times, expressed
 56      /// </summary>
 57      /// <typeparam name="T">The type of item to repeat.</typeparam>
 58      /// <param name="item">The item to repeat.</param>
 59      /// <param name="count">Amount of times to repeat the <paramref name="item"/>, as 64-bit integer.</param>
 60      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 61      /// <returns>An empty <see cref="IAsyncEnumerable{T}"/> if <paramref name="count"/> is <c>0</c> or less; otherwise
 62      /// <seealso cref="System.Linq.Enumerable.Repeat{TResult}(TResult, Int32)"/>
 63      /// <seealso cref="Repeat{T}(T, Int32, IAsyncProvider)"/>
 64      public static IAsyncEnumerable<T> Repeat<T>(
 65         T item,
 66         Int64 count,
 67         IAsyncProvider asyncProvider
 68         )
 69      {
 370         return count <= 0 ?
 371            EmptyAsync<T>.Enumerable :
 1372            Neverending( () => item, asyncProvider ).Take( count );
 73      }
 74
 75      /// <summary>
 76      /// Returns <see cref="IAsyncEnumerable{T}"/> that will return the result of given synchronous item factory callba
 77      /// </summary>
 78      /// <typeparam name="T">The type of item to repeat.</typeparam>
 79      /// <param name="generator">The synchronous callback to generate an item to repeat.</param>
 80      /// <param name="count">Amount of times to repeat the item.</param>
 81      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 82      /// <returns>An empty <see cref="IAsyncEnumerable{T}"/> if <paramref name="count"/> is <c>0</c> or less; otherwise
 83      /// <seealso cref="System.Linq.Enumerable.Repeat{TResult}(TResult, Int32)"/>
 84      public static IAsyncEnumerable<T> Repeat<T>(
 85         Func<T> generator,
 86         Int32 count,
 87         IAsyncProvider asyncProvider
 88         )
 89      {
 190         return count <= 0 ?
 191            EmptyAsync<T>.Enumerable :
 192            Neverending( generator, asyncProvider ).Take( count );
 93      }
 94
 95      /// <summary>
 96      /// Returns <see cref="IAsyncEnumerable{T}"/> that will return the result of given potentially asynchronous item f
 97      /// </summary>
 98      /// <typeparam name="T">The type of item to repeat.</typeparam>
 99      /// <param name="asyncGenerator">The potentially asynchronous callback to generate an item to repeat.</param>
 100      /// <param name="count">Amount of times to repeat the item.</param>
 101      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 102      /// <returns>An empty <see cref="IAsyncEnumerable{T}"/> if <paramref name="count"/> is <c>0</c> or less; otherwise
 103      /// <seealso cref="System.Linq.Enumerable.Repeat{TResult}(TResult, Int32)"/>
 104      public static IAsyncEnumerable<T> Repeat<T>(
 105         Func<ValueTask<T>> asyncGenerator,
 106         Int32 count,
 107         IAsyncProvider asyncProvider
 108         )
 109      {
 1110         return count <= 0 ?
 1111            EmptyAsync<T>.Enumerable :
 1112            Neverending( asyncGenerator, asyncProvider ).Take( count );
 113      }
 114
 115      /// <summary>
 116      /// Returns <see cref="IAsyncEnumerable{T}"/> that will return the result of given synchronous item factory callba
 117      /// </summary>
 118      /// <typeparam name="T">The type of item to repeat.</typeparam>
 119      /// <param name="generator">The synchronous callback to generate an item to repeat.</param>
 120      /// <param name="count">Amount of times to repeat the item.</param>
 121      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 122      /// <returns>An empty <see cref="IAsyncEnumerable{T}"/> if <paramref name="count"/> is <c>0</c> or less; otherwise
 123      public static IAsyncEnumerable<T> Repeat<T>(
 124         Func<T> generator,
 125         Int64 count,
 126         IAsyncProvider asyncProvider
 127         )
 128      {
 1129         return count <= 0 ?
 1130            EmptyAsync<T>.Enumerable :
 1131            Neverending( generator, asyncProvider ).Take( count );
 132      }
 133
 134      /// <summary>
 135      /// Returns <see cref="IAsyncEnumerable{T}"/> that will return the result of given potentially asynchronous item f
 136      /// </summary>
 137      /// <typeparam name="T">The type of item to repeat.</typeparam>
 138      /// <param name="asyncGenerator">The potentially asynchronous callback to generate an item to repeat.</param>
 139      /// <param name="count">Amount of times to repeat the item.</param>
 140      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 141      /// <returns>An empty <see cref="IAsyncEnumerable{T}"/> if <paramref name="count"/> is <c>0</c> or less; otherwise
 142      public static IAsyncEnumerable<T> Repeat<T>(
 143         Func<ValueTask<T>> asyncGenerator,
 144         Int64 count,
 145         IAsyncProvider asyncProvider
 146         )
 147      {
 1148         return count <= 0 ?
 1149            EmptyAsync<T>.Enumerable :
 1150            Neverending( asyncGenerator, asyncProvider ).Take( count );
 151      }
 152
 153
 154      /// <summary>
 155      /// Returns <see cref="IAsyncEnumerable{T}"/> that will return numbers in given range specification.
 156      /// </summary>
 157      /// <param name="initial">The start of the range, inclusive.</param>
 158      /// <param name="target">The end of the range, exclusive.</param>
 159      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 160      /// <param name="step">The amount to increase for each number within the range. By default, is <c>1</c> for increa
 161      /// <returns>An enumerable that contains numbers within the given range specification.</returns>
 162      /// <remarks>
 163      /// Note that unlike <see cref="System.Linq.Enumerable.Range(Int32, Int32)"/>, this method has exclusive _maximum_
 164      /// This method also handles both increasing and decreasing number ranges.
 165      /// </remarks>
 166      /// <seealso cref="System.Linq.Enumerable.Range(Int32, Int32)"/>
 167      public static IAsyncEnumerable<Int32> Range(
 168         Int32 initial,
 169         Int32 target,
 170         IAsyncProvider asyncProvider,
 171         Int32 step = 1
 172         )
 173      {
 174         IAsyncEnumerable<Int32> retVal;
 9175         if ( target > initial )
 176         {
 177            // Increasing range from initial to target, step must be 1 or greater
 7178            step = Math.Max( 1, step );
 7179            retVal = AsyncEnumerationFactory.CreateStatefulWrappingEnumerable( () =>
 7180            {
 14181               var current = initial;
 14182               return AsyncEnumerationFactory.CreateSynchronousWrappingStartInfo(
 14183               ( out Boolean success ) =>
 14184               {
 45185                  var prev = current;
 45186                  success = current < target;
 45187                  current += step;
 45188                  return prev;
 14189               } );
 7190            }, asyncProvider );
 7191         }
 2192         else if ( initial == target )
 193         {
 194            // Empty
 1195            retVal = EmptyAsync<Int32>.Enumerable;
 1196         }
 197         else
 198         {
 199            // Decreasing range from target to initial, step must be -1 or less
 1200            step = Math.Min( -1, step );
 1201            retVal = AsyncEnumerationFactory.CreateStatefulWrappingEnumerable( () =>
 1202            {
 2203               var current = initial;
 2204               return AsyncEnumerationFactory.CreateSynchronousWrappingStartInfo(
 2205               ( out Boolean success ) =>
 2206               {
 18207                  var prev = current;
 18208                  success = current > target;
 18209                  current += step; // Notice it is plus, since the "step" variable is always negative.
 18210                  return prev;
 2211               } );
 1212            }, asyncProvider );
 213         }
 214
 9215         return retVal;
 216      }
 217
 218      /// <summary>
 219      /// Returns <see cref="IAsyncEnumerable{T}"/> that will return numbers in given range specification, as 64-bit int
 220      /// </summary>
 221      /// <param name="initial">The start of the range, inclusive.</param>
 222      /// <param name="target">The end of the range, exclusive.</param>
 223      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 224      /// <param name="step">The amount to increase for each number within the range. By default, is <c>1</c> for increa
 225      /// <returns>An enumerable that contains numbers within the given range specification.</returns>
 226      /// <remarks>
 227      /// Note that unlike <see cref="System.Linq.Enumerable.Range(Int32, Int32)"/>, this method has exclusive _maximum_
 228      /// This method also handles both increasing and decreasing number ranges.
 229      /// </remarks>
 230      /// <seealso cref="System.Linq.Enumerable.Range(Int32, Int32)"/>
 231      public static IAsyncEnumerable<Int64> Range(
 232         Int64 initial,
 233         Int64 target,
 234         IAsyncProvider asyncProvider,
 235         Int64 step = 1
 236         )
 237      {
 238         IAsyncEnumerable<Int64> retVal;
 3239         if ( target > initial )
 240         {
 241            // Increasing range from initial to target, step must be 1 or greater
 1242            step = Math.Max( 1, step );
 1243            retVal = AsyncEnumerationFactory.CreateStatefulWrappingEnumerable( () =>
 1244            {
 2245               var current = initial;
 2246               return AsyncEnumerationFactory.CreateSynchronousWrappingStartInfo(
 2247               ( out Boolean success ) =>
 2248               {
 18249                  var prev = current;
 18250                  success = current < target;
 18251                  current += step;
 18252                  return prev;
 2253               } );
 1254            }, asyncProvider );
 1255         }
 2256         else if ( initial == target )
 257         {
 258            // Empty
 1259            retVal = EmptyAsync<Int64>.Enumerable;
 1260         }
 261         else
 262         {
 263            // Decreasing range from target to initial, step must be -1 or less
 1264            step = Math.Min( -1, step );
 1265            retVal = AsyncEnumerationFactory.CreateStatefulWrappingEnumerable( () =>
 1266            {
 2267               var current = initial;
 2268               return AsyncEnumerationFactory.CreateSynchronousWrappingStartInfo(
 2269               ( out Boolean success ) =>
 2270               {
 18271                  var prev = current;
 18272                  success = current > target;
 18273                  current += step; // Notice it is plus, since the "step" variable is always negative.
 18274                  return prev;
 2275               } );
 1276            }, asyncProvider );
 277         }
 278
 3279         return retVal;
 280      }
 281
 282      /// <summary>
 283      /// Returns <see cref="IAsyncEnumerable{T}"/> that will indefinetly repeat the given value.
 284      /// </summary>
 285      /// <typeparam name="T">The type of item to repeat.</typeparam>
 286      /// <param name="item">An item to repeat.</param>
 287      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 288      /// <returns>An enumerable that will indefinetly repeat the given value.</returns>
 289      public static IAsyncEnumerable<T> Neverending<T>(
 290         T item,
 291         IAsyncProvider asyncProvider
 292         )
 293      {
 3294         return AsyncEnumerationFactory.CreateStatelessWrappingEnumerable( AsyncEnumerationFactory.CreateSynchronousWrap
 3295            ( out Boolean success ) =>
 3296            {
 14297               success = true;
 14298               return item;
 3299            }
 3300            ), asyncProvider );
 301      }
 302
 303      /// <summary>
 304      /// Returns <see cref="IAsyncEnumerable{T}"/> that will indefinetly repeat the value returned by given synchronous
 305      /// </summary>
 306      /// <typeparam name="T">The type of item to repeat.</typeparam>
 307      /// <param name="generator">A synchronous callback to dynamically generate the value to repeat.</param>
 308      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 309      /// <returns>An enumerable that will indefinetly repeat the given value.</returns>
 310      public static IAsyncEnumerable<T> Neverending<T>(
 311         Func<T> generator,
 312         IAsyncProvider asyncProvider
 313         )
 314      {
 7315         return AsyncEnumerationFactory.CreateStatelessWrappingEnumerable( AsyncEnumerationFactory.CreateSynchronousWrap
 7316            ( out Boolean success ) =>
 7317            {
 54318               success = true;
 54319               return generator();
 7320            }
 7321            ), asyncProvider );
 322      }
 323
 324      /// <summary>
 325      /// Returns <see cref="IAsyncEnumerable{T}"/> that will indefinetly repeat the value returned by given potentially
 326      /// </summary>
 327      /// <typeparam name="T">The type of item to repeat.</typeparam>
 328      /// <param name="asyncGenerator">A potentially asynchronous callback to dynamically generate the value to repeat.<
 329      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 330      /// <returns>An enumerable that will indefinetly repeat the given value.</returns>
 331      public static IAsyncEnumerable<T> Neverending<T>(
 332         Func<ValueTask<T>> asyncGenerator,
 333         IAsyncProvider asyncProvider
 334         )
 335      {
 4336         return AsyncEnumerationFactory.CreateSequentialEnumerable( () => AsyncEnumerationFactory.CreateSequentialStartI
 4337            async () =>
 4338            {
 24339               return (true, await asyncGenerator());
 24340            },
 4341            null
 4342            ), asyncProvider );
 343      }
 344   }
 345}