Files
sharpcompress/src/SharpCompress/Polyfills/AsyncEnumerableExtensions.cs
Adam Hathcock 07319f61bf Minor changes
2026-06-01 13:41:17 +01:00

182 lines
4.7 KiB
C#

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<T> Empty<T>()
where T : notnull
{
await Task.Yield();
yield break;
}
}
public static class EnumerableExtensions
{
public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(this IEnumerable<T> source)
{
foreach (var item in source)
{
yield return item;
}
}
}
public static class AsyncEnumerableExtensions
{
#if !NET10_0_OR_GREATER
extension<T>(IAsyncEnumerable<T> source)
{
public async IAsyncEnumerable<TResult> Select<TResult>(Func<T, TResult> selector)
{
await foreach (var element in source.ConfigureAwait(false))
{
yield return selector(element);
}
}
public async ValueTask<int> 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<T> Take(int count)
{
await foreach (var element in source.ConfigureAwait(false))
{
yield return element;
if (--count == 0)
{
break;
}
}
}
public async ValueTask<List<T>> ToListAsync()
{
var list = new List<T>();
await foreach (var item in source.ConfigureAwait(false))
{
list.Add(item);
}
return list;
}
public async ValueTask<bool> AllAsync(Func<T, bool> predicate)
{
await foreach (var item in source.ConfigureAwait(false))
{
if (!predicate(item))
{
return false;
}
}
return true;
}
public async IAsyncEnumerable<T> Where(Func<T, bool> predicate)
{
await foreach (var item in source.ConfigureAwait(false))
{
if (predicate(item))
{
yield return item;
}
}
}
public async ValueTask<T> SingleAsync(Func<T, bool>? predicate = null)
{
IAsyncEnumerator<T> 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<T> FirstAsync()
{
await foreach (var item in source.ConfigureAwait(false))
{
return item;
}
throw new ArchiveOperationException("The source sequence is empty.");
}
public async ValueTask<T?> FirstOrDefaultAsync(
CancellationToken cancellationToken = default
)
{
await foreach (
var item in source.WithCancellation(cancellationToken).ConfigureAwait(false)
)
{
return item;
}
return default;
}
}
#endif
public static async IAsyncEnumerable<TResult> CastAsync<TResult>(
this IAsyncEnumerable<object?> source
)
where TResult : class
{
await foreach (var item in source.ConfigureAwait(false))
{
yield return (item as TResult).NotNull();
}
}
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.ConfigureAwait(false))
{
result = func(result, element);
}
return result;
}
}