Files
sharpcompress/src/SharpCompress/Polyfills/AsyncEnumerableExtensions.cs
Adam Hathcock 0b8081f320 gzip fixes
2026-01-13 14:24:36 +00:00

184 lines
4.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace SharpCompress;
public static class AsyncEnumerableEx
{
public static async IAsyncEnumerable<T> Empty<T>()
where T : notnull
{
await Task.CompletedTask;
yield break;
}
}
public static class EnumerableExtensions
{
public static async IAsyncEnumerable<T> ToAsyncEnumerable<T>(this IEnumerable<T> source)
{
await Task.CompletedTask;
foreach (var item in source)
{
yield return item;
}
}
}
public static class AsyncEnumerableExtensions
{
public static async IAsyncEnumerable<T> TakeAsync<T>(
this IAsyncEnumerable<T> source,
int count)
{
await foreach (var element in source)
{
yield return element;
if (--count == 0)
{
break;
}
}
}
public static async ValueTask<List<T>> ToListAsync<T>(this IAsyncEnumerable<T> source)
{
var list = new List<T>();
await foreach (var item in source)
{
list.Add(item);
}
return list;
}
public static async IAsyncEnumerable<TResult> CastAsync<TResult>(
this IAsyncEnumerable<object?> source
)
where TResult : class
{
await foreach (var item in source)
{
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
)
{
TAccumulate result = seed;
await foreach (var element in source)
{
result = func(result, element);
}
return result;
}
public static async ValueTask<bool> AllAsync<T>(
this IAsyncEnumerable<T> source,
Func<T, bool> predicate
)
{
await foreach (var item in source)
{
if (!predicate(item))
{
return false;
}
}
return true;
}
public static IAsyncEnumerable<T> Where<T>(
this IAsyncEnumerable<T> source,
Func<T, bool> predicate
)
{
return WhereIterator(source, predicate);
}
private static async IAsyncEnumerable<T> WhereIterator<T>(
IAsyncEnumerable<T> source,
Func<T, bool> predicate
)
{
await foreach (var item in source)
{
if (predicate(item))
{
yield return item;
}
}
}
public static async IAsyncEnumerable<T> WhereAsync<T>(
this IAsyncEnumerable<T> source,
Func<T, bool> predicate
)
{
await foreach (var item in source)
{
if (predicate(item))
{
yield return item;
}
}
}
public static async ValueTask<T> SingleAsync<T>(
this IAsyncEnumerable<T> source,
Func<T, bool>? predicate = null
)
{
IAsyncEnumerator<T> enumerator;
if (predicate is null)
{
enumerator = source.GetAsyncEnumerator();
}
else
{
enumerator = source.WhereAsync(predicate).GetAsyncEnumerator();
}
if (!await enumerator.MoveNextAsync())
{
throw new InvalidOperationException("The source sequence is empty.");
}
var value = enumerator.Current;
if (await enumerator.MoveNextAsync())
{
throw new InvalidOperationException(
"The source sequence contains more than one element."
);
}
return value;
}
public static async ValueTask<T> FirstAsync<T>(this IAsyncEnumerable<T> source)
{
await foreach (var item in source)
{
return item;
}
throw new InvalidOperationException("The source sequence is empty.");
}
public static async ValueTask<T?> FirstOrDefaultAsync<T>(this IAsyncEnumerable<T> source)
{
await foreach (var item in source)
{
return item;
}
return default;
}
}