Files
sharpcompress/src/SharpCompress/Polyfills/AsyncEnumerableExtensions.cs

181 lines
4.5 KiB
C#
Raw Normal View History

2026-01-07 14:47:20 +00:00
using System;
using System.Collections.Generic;
2026-01-13 14:24:36 +00:00
using System.Threading;
2026-01-07 14:47:20 +00:00
using System.Threading.Tasks;
using SharpCompress.Common;
2026-01-07 14:47:20 +00:00
namespace SharpCompress;
2026-01-08 09:14:46 +00:00
public static class AsyncEnumerableEx
{
public static async IAsyncEnumerable<T> Empty<T>()
where T : notnull
{
2026-02-10 14:41:26 +00:00
await Task.Yield();
2026-01-08 09:41:48 +00:00
yield break;
2026-01-08 09:14:46 +00:00
}
}
public static class EnumerableExtensions
{
public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(this IEnumerable<T> source)
{
2026-02-10 14:41:26 +00:00
await Task.Yield();
foreach (var item in source)
{
yield return item;
}
}
}
2026-01-07 14:47:20 +00:00
public static class AsyncEnumerableExtensions
{
#if !NET10_0_OR_GREATER
extension<T>(IAsyncEnumerable<T> source)
2026-01-13 14:28:45 +00:00
{
public async IAsyncEnumerable<TResult> Select<TResult>(Func<T, TResult> selector)
2026-01-13 14:29:10 +00:00
{
await foreach (var element in source)
2026-01-13 14:29:10 +00:00
{
yield return selector(element);
2026-01-13 14:29:10 +00:00
}
2026-01-13 14:28:45 +00:00
}
public async ValueTask<int> CountAsync(CancellationToken cancellationToken = default)
2026-01-13 14:24:36 +00:00
{
await using var e = source.GetAsyncEnumerator(cancellationToken);
2026-01-13 14:24:36 +00:00
var count = 0;
2026-02-10 12:40:30 +00:00
while (await e.MoveNextAsync().ConfigureAwait(false))
2026-01-13 14:24:36 +00:00
{
checked
{
count++;
}
2026-01-13 14:24:36 +00:00
}
return count;
}
2026-01-08 09:41:48 +00:00
public async IAsyncEnumerable<T> Take(int count)
2026-01-08 09:14:46 +00:00
{
await foreach (var element in source)
{
yield return element;
2026-01-08 09:41:48 +00:00
if (--count == 0)
{
break;
}
}
2026-01-12 13:45:21 +00:00
}
public async ValueTask<List<T>> ToListAsync()
2026-01-08 09:14:46 +00:00
{
var list = new List<T>();
await foreach (var item in source)
2026-01-08 09:14:46 +00:00
{
list.Add(item);
2026-01-08 09:14:46 +00:00
}
return list;
2026-01-08 09:14:46 +00:00
}
2026-01-08 09:41:48 +00:00
public async ValueTask<bool> AllAsync(Func<T, bool> predicate)
2026-01-07 14:47:20 +00:00
{
await foreach (var item in source)
2026-01-07 14:47:20 +00:00
{
if (!predicate(item))
{
return false;
}
2026-01-07 14:47:20 +00:00
}
return true;
2026-01-07 14:47:20 +00:00
}
public async IAsyncEnumerable<T> Where(Func<T, bool> predicate)
{
await foreach (var item in source)
{
if (predicate(item))
{
yield return item;
}
}
}
public async ValueTask<T> SingleAsync(Func<T, bool>? predicate = null)
2026-01-13 14:24:36 +00:00
{
IAsyncEnumerator<T> enumerator;
if (predicate is null)
{
enumerator = source.GetAsyncEnumerator();
}
else
{
enumerator = source.Where(predicate).GetAsyncEnumerator();
}
2026-02-10 12:40:30 +00:00
if (!await enumerator.MoveNextAsync().ConfigureAwait(false))
{
throw new ArchiveOperationException("The source sequence is empty.");
}
var value = enumerator.Current;
2026-02-10 12:40:30 +00:00
if (await enumerator.MoveNextAsync().ConfigureAwait(false))
{
throw new ArchiveOperationException(
"The source sequence contains more than one element."
);
}
return value;
2026-01-13 14:24:36 +00:00
}
public async ValueTask<T> FirstAsync()
2026-01-12 14:57:13 +00:00
{
await foreach (var item in source)
{
return item;
}
throw new ArchiveOperationException("The source sequence is empty.");
2026-01-12 14:57:13 +00:00
}
public async ValueTask<T?> FirstOrDefaultAsync(
CancellationToken cancellationToken = default
)
2026-01-12 14:57:13 +00:00
{
await foreach (var item in source.WithCancellation(cancellationToken))
{
return item;
}
return default;
2026-01-12 14:57:13 +00:00
}
}
#endif
2026-01-12 14:57:13 +00:00
public static async IAsyncEnumerable<TResult> CastAsync<TResult>(
this IAsyncEnumerable<object?> source
)
where TResult : class
{
await foreach (var item in source)
2026-01-07 14:47:20 +00:00
{
yield return (item as TResult).NotNull();
}
}
2026-01-07 14:47:20 +00:00
public static async ValueTask<TAccumulate> AggregateAsync<TAccumulate, T>(
this IAsyncEnumerable<T> source,
TAccumulate seed,
Func<TAccumulate, T, TAccumulate> func
)
{
var result = seed;
await foreach (var element in source)
{
result = func(result, element);
2026-01-08 09:14:46 +00:00
}
return result;
2026-01-07 14:47:20 +00:00
}
}