using Cysharp.Threading.Tasks.Internal; using System; using System.Collections.Generic; using System.Threading; namespace Cysharp.Threading.Tasks.Linq { public static partial class UniTaskAsyncEnumerable { public static UniTask<Dictionary<TKey, TSource>> ToDictionaryAsync<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); return ToDictionary.ToDictionaryAsync(source, keySelector, EqualityComparer<TKey>.Default, cancellationToken); } public static UniTask<Dictionary<TKey, TSource>> ToDictionaryAsync<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); Error.ThrowArgumentNullException(comparer, nameof(comparer)); return ToDictionary.ToDictionaryAsync(source, keySelector, comparer, cancellationToken); } public static UniTask<Dictionary<TKey, TElement>> ToDictionaryAsync<TSource, TKey, TElement>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); return ToDictionary.ToDictionaryAsync(source, keySelector, elementSelector, EqualityComparer<TKey>.Default, cancellationToken); } public static UniTask<Dictionary<TKey, TElement>> ToDictionaryAsync<TSource, TKey, TElement>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); Error.ThrowArgumentNullException(comparer, nameof(comparer)); return ToDictionary.ToDictionaryAsync(source, keySelector, elementSelector, comparer, cancellationToken); } public static UniTask<Dictionary<TKey, TSource>> ToDictionaryAwaitAsync<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); return ToDictionary.ToDictionaryAwaitAsync(source, keySelector, EqualityComparer<TKey>.Default, cancellationToken); } public static UniTask<Dictionary<TKey, TSource>> ToDictionaryAwaitAsync<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); Error.ThrowArgumentNullException(comparer, nameof(comparer)); return ToDictionary.ToDictionaryAwaitAsync(source, keySelector, comparer, cancellationToken); } public static UniTask<Dictionary<TKey, TElement>> ToDictionaryAwaitAsync<TSource, TKey, TElement>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TSource, UniTask<TElement>> elementSelector, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); return ToDictionary.ToDictionaryAwaitAsync(source, keySelector, elementSelector, EqualityComparer<TKey>.Default, cancellationToken); } public static UniTask<Dictionary<TKey, TElement>> ToDictionaryAwaitAsync<TSource, TKey, TElement>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TSource, UniTask<TElement>> elementSelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); Error.ThrowArgumentNullException(comparer, nameof(comparer)); return ToDictionary.ToDictionaryAwaitAsync(source, keySelector, elementSelector, comparer, cancellationToken); } public static UniTask<Dictionary<TKey, TSource>> ToDictionaryAwaitWithCancellationAsync<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); return ToDictionary.ToDictionaryAwaitWithCancellationAsync(source, keySelector, EqualityComparer<TKey>.Default, cancellationToken); } public static UniTask<Dictionary<TKey, TSource>> ToDictionaryAwaitWithCancellationAsync<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); Error.ThrowArgumentNullException(comparer, nameof(comparer)); return ToDictionary.ToDictionaryAwaitWithCancellationAsync(source, keySelector, comparer, cancellationToken); } public static UniTask<Dictionary<TKey, TElement>> ToDictionaryAwaitWithCancellationAsync<TSource, TKey, TElement>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TSource, CancellationToken, UniTask<TElement>> elementSelector, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); return ToDictionary.ToDictionaryAwaitWithCancellationAsync(source, keySelector, elementSelector, EqualityComparer<TKey>.Default, cancellationToken); } public static UniTask<Dictionary<TKey, TElement>> ToDictionaryAwaitWithCancellationAsync<TSource, TKey, TElement>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TSource, CancellationToken, UniTask<TElement>> elementSelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector)); Error.ThrowArgumentNullException(comparer, nameof(comparer)); return ToDictionary.ToDictionaryAwaitWithCancellationAsync(source, keySelector, elementSelector, comparer, cancellationToken); } } internal static class ToDictionary { internal static async UniTask<Dictionary<TKey, TSource>> ToDictionaryAsync<TSource, TKey>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken) { var dict = new Dictionary<TKey, TSource>(comparer); var e = source.GetAsyncEnumerator(cancellationToken); try { while (await e.MoveNextAsync()) { var v = e.Current; var key = keySelector(v); dict.Add(key, v); } } finally { if (e != null) { await e.DisposeAsync(); } } return dict; } internal static async UniTask<Dictionary<TKey, TElement>> ToDictionaryAsync<TSource, TKey, TElement>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken) { var dict = new Dictionary<TKey, TElement>(comparer); var e = source.GetAsyncEnumerator(cancellationToken); try { while (await e.MoveNextAsync()) { var v = e.Current; var key = keySelector(v); var value = elementSelector(v); dict.Add(key, value); } } finally { if (e != null) { await e.DisposeAsync(); } } return dict; } // with await internal static async UniTask<Dictionary<TKey, TSource>> ToDictionaryAwaitAsync<TSource, TKey>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken) { var dict = new Dictionary<TKey, TSource>(comparer); var e = source.GetAsyncEnumerator(cancellationToken); try { while (await e.MoveNextAsync()) { var v = e.Current; var key = await keySelector(v); dict.Add(key, v); } } finally { if (e != null) { await e.DisposeAsync(); } } return dict; } internal static async UniTask<Dictionary<TKey, TElement>> ToDictionaryAwaitAsync<TSource, TKey, TElement>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TSource, UniTask<TElement>> elementSelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken) { var dict = new Dictionary<TKey, TElement>(comparer); var e = source.GetAsyncEnumerator(cancellationToken); try { while (await e.MoveNextAsync()) { var v = e.Current; var key = await keySelector(v); var value = await elementSelector(v); dict.Add(key, value); } } finally { if (e != null) { await e.DisposeAsync(); } } return dict; } // with cancellation internal static async UniTask<Dictionary<TKey, TSource>> ToDictionaryAwaitWithCancellationAsync<TSource, TKey>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken) { var dict = new Dictionary<TKey, TSource>(comparer); var e = source.GetAsyncEnumerator(cancellationToken); try { while (await e.MoveNextAsync()) { var v = e.Current; var key = await keySelector(v, cancellationToken); dict.Add(key, v); } } finally { if (e != null) { await e.DisposeAsync(); } } return dict; } internal static async UniTask<Dictionary<TKey, TElement>> ToDictionaryAwaitWithCancellationAsync<TSource, TKey, TElement>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TSource, CancellationToken, UniTask<TElement>> elementSelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken) { var dict = new Dictionary<TKey, TElement>(comparer); var e = source.GetAsyncEnumerator(cancellationToken); try { while (await e.MoveNextAsync()) { var v = e.Current; var key = await keySelector(v, cancellationToken); var value = await elementSelector(v, cancellationToken); dict.Add(key, value); } } finally { if (e != null) { await e.DisposeAsync(); } } return dict; } } }