using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using SharpCompress.Common; namespace SharpCompress; public static class AsyncEnumerableEx { public static async IAsyncEnumerable Empty() where T : notnull { await Task.Yield(); yield break; } } public static class EnumerableExtensions { public static async IAsyncEnumerable ToAsyncEnumerable(this IEnumerable source) { await Task.Yield(); foreach (var item in source) { yield return item; } } } public static class AsyncEnumerableExtensions { #if !NET10_0_OR_GREATER extension(IAsyncEnumerable source) { public async IAsyncEnumerable Select(Func selector) { await foreach (var element in source) { yield return selector(element); } } public async ValueTask CountAsync(CancellationToken cancellationToken = default) { await using var e = source.GetAsyncEnumerator(cancellationToken); var count = 0; while (await e.MoveNextAsync().ConfigureAwait(false)) { checked { count++; } } return count; } public async IAsyncEnumerable Take(int count) { await foreach (var element in source) { yield return element; if (--count == 0) { break; } } } public async ValueTask> ToListAsync() { var list = new List(); await foreach (var item in source) { list.Add(item); } return list; } public async ValueTask AllAsync(Func predicate) { await foreach (var item in source) { if (!predicate(item)) { return false; } } return true; } public async IAsyncEnumerable Where(Func predicate) { await foreach (var item in source) { if (predicate(item)) { yield return item; } } } public async ValueTask SingleAsync(Func? predicate = null) { IAsyncEnumerator enumerator; if (predicate is null) { enumerator = source.GetAsyncEnumerator(); } else { enumerator = source.Where(predicate).GetAsyncEnumerator(); } if (!await enumerator.MoveNextAsync().ConfigureAwait(false)) { throw new ArchiveOperationException("The source sequence is empty."); } var value = enumerator.Current; if (await enumerator.MoveNextAsync().ConfigureAwait(false)) { throw new ArchiveOperationException( "The source sequence contains more than one element." ); } return value; } public async ValueTask FirstAsync() { await foreach (var item in source) { return item; } throw new ArchiveOperationException("The source sequence is empty."); } public async ValueTask FirstOrDefaultAsync( CancellationToken cancellationToken = default ) { await foreach (var item in source.WithCancellation(cancellationToken)) { return item; } return default; } } #endif public static async IAsyncEnumerable CastAsync( this IAsyncEnumerable source ) where TResult : class { await foreach (var item in source) { yield return (item as TResult).NotNull(); } } public static async ValueTask AggregateAsync( this IAsyncEnumerable source, TAccumulate seed, Func func ) { var result = seed; await foreach (var element in source) { result = func(result, element); } return result; } }