using System; using System.Threading; namespace Cysharp.Threading.Tasks.Linq { public static partial class UniTaskAsyncEnumerable { public static IUniTaskAsyncEnumerable Where(this IUniTaskAsyncEnumerable source, Func predicate) { return new Cysharp.Threading.Tasks.Linq.Where(source, predicate); } public static IUniTaskAsyncEnumerable WhereAwait(this IUniTaskAsyncEnumerable source, Func> predicate) { return new Cysharp.Threading.Tasks.Linq.WhereAwait(source, predicate); } } internal sealed class Where : IUniTaskAsyncEnumerable { readonly IUniTaskAsyncEnumerable source; readonly Func predicate; public Where(IUniTaskAsyncEnumerable source, Func predicate) { this.source = source; this.predicate = predicate; } public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) { return new Enumerator(source, predicate, cancellationToken); } class Enumerator : AsyncEnumeratorBase { readonly Func predicate; public Enumerator(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken) : base(source, cancellationToken) { this.predicate = predicate; } protected override bool TryMoveNextCore(bool sourceHasCurrent, out bool result) { if (sourceHasCurrent) { if (predicate(SourceCurrent)) { Current = SourceCurrent; result = true; return true; } else { result = default; return false; } } result = false; return true; } } } internal sealed class WhereAwait : IUniTaskAsyncEnumerable { readonly IUniTaskAsyncEnumerable source; readonly Func> predicate; public WhereAwait(IUniTaskAsyncEnumerable source, Func> predicate) { this.source = source; this.predicate = predicate; } public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) { return new Enumerator(source, predicate, cancellationToken); } class Enumerator : AsyncEnumeratorAwaitSelectorBase { readonly Func> predicate; public Enumerator(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) : base(source, cancellationToken) { this.predicate = predicate; } protected override UniTask TransformAsync(TSource sourceCurrent) { return predicate(sourceCurrent); } protected override bool TrySetCurrentCore(bool awaitResult) { if (awaitResult) { Current = SourceCurrent; return true; } else { return false; } } } } }