Minecraft-Phantom-Panel/Utils/Phantom.Utils/Collections/EnumerableExtensions.cs

57 lines
2.0 KiB
C#

using System.Collections.Immutable;
namespace Phantom.Utils.Collections;
public static class EnumerableExtensions {
public static async Task<ImmutableArray<TSource>> ToImmutableArrayAsync<TSource>(this IAsyncEnumerable<TSource> source, CancellationToken cancellationToken = default) {
var builder = ImmutableArray.CreateBuilder<TSource>();
await foreach (var element in source.WithCancellation(cancellationToken)) {
builder.Add(element);
}
return builder.ToImmutable();
}
public static async Task<ImmutableArray<TSource>> ToImmutableArrayCatchingExceptionsAsync<TSource>(this IAsyncEnumerable<TSource> source, Action<Exception> onException, CancellationToken cancellationToken = default) {
var builder = ImmutableArray.CreateBuilder<TSource>();
await using (var enumerator = source.GetAsyncEnumerator(cancellationToken)) {
while (true) {
try {
if (!await enumerator.MoveNextAsync()) {
break;
}
} catch (Exception e) {
onException(e);
continue;
}
builder.Add(enumerator.Current);
}
}
return builder.ToImmutable();
}
public static async Task<ImmutableHashSet<TSource>> ToImmutableSetAsync<TSource>(this IAsyncEnumerable<TSource> source, CancellationToken cancellationToken = default) {
var builder = ImmutableHashSet.CreateBuilder<TSource>();
await foreach (var element in source.WithCancellation(cancellationToken)) {
builder.Add(element);
}
return builder.ToImmutable();
}
public static async Task<ImmutableDictionary<TKey, TValue>> ToImmutableDictionaryAsync<TSource, TKey, TValue>(this IAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TValue> valueSelector, CancellationToken cancellationToken = default) where TKey : notnull {
var builder = ImmutableDictionary.CreateBuilder<TKey, TValue>();
await foreach (var element in source.WithCancellation(cancellationToken)) {
builder.Add(keySelector(element), valueSelector(element));
}
return builder.ToImmutable();
}
}