<PackageReference Include="NUnit" Version="4.1.0" />

AsyncEnumerableAdapter

static class AsyncEnumerableAdapter
using NUnit.Framework.Internal.Extensions; using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; namespace NUnit.Framework.Internal { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] internal static class AsyncEnumerableAdapter { [System.Runtime.CompilerServices.Nullable(0)] private class AsyncEnumerableWrapper : IEnumerable<object>, IEnumerable { private readonly AsyncEnumerableShapeInfo _shape; private readonly object _asyncEnumerable; private readonly MethodInfo _getAsyncEnumeratorMethod; private static readonly object[] EnumeratorArgs = new object[1] { CancellationToken.None }; public AsyncEnumerableWrapper(AsyncEnumerableShapeInfo shape, object asyncEnumerable) { _shape = shape; _asyncEnumerable = asyncEnumerable; _getAsyncEnumeratorMethod = shape.GetAsyncEnumeratorMethod; } [return: System.Runtime.CompilerServices.Nullable(new byte[] { 1, 2 })] public IEnumerator<object> GetEnumerator() { return new AsyncEnumeratorWrapper(_shape, _getAsyncEnumeratorMethod.Invoke(_asyncEnumerable, EnumeratorArgs)); } IEnumerator IEnumerable.GetEnumerator() { return new AsyncEnumeratorWrapper(_shape, _getAsyncEnumeratorMethod.Invoke(_asyncEnumerable, EnumeratorArgs)); } } [System.Runtime.CompilerServices.NullableContext(0)] private class AsyncEnumeratorWrapper : IEnumerator<object>, IDisposable, IEnumerator { [System.Runtime.CompilerServices.Nullable(1)] private readonly object _asyncEnumerator; [System.Runtime.CompilerServices.Nullable(1)] private readonly MethodInfo _disposeAsyncMethod; [System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0 })] private readonly Func<ValueTask<bool>> _moveNextAsyncMethod; [System.Runtime.CompilerServices.Nullable(new byte[] { 1, 2 })] private readonly Func<object> _getCurrentMethod; [System.Runtime.CompilerServices.Nullable(2)] public object Current { [System.Runtime.CompilerServices.NullableContext(2)] get { return _getCurrentMethod(); } } [System.Runtime.CompilerServices.NullableContext(1)] public AsyncEnumeratorWrapper(AsyncEnumerableShapeInfo shape, object asyncEnumerator) { _asyncEnumerator = asyncEnumerator; _disposeAsyncMethod = shape.DisposeAsyncMethod; _moveNextAsyncMethod = MethodInfoExtensions.CreateDelegate<Func<ValueTask<bool>>>(shape.MoveNextAsyncMethod, asyncEnumerator); _getCurrentMethod = MethodInfoExtensions.CreateDelegate<Func<object>>(shape.CurrentProperty.GetGetMethod(), asyncEnumerator); } public void Dispose() { AsyncToSyncAdapter.Await(() => _disposeAsyncMethod.Invoke(_asyncEnumerator, null)); } public bool MoveNext() { return AsyncToSyncAdapter.Await<bool>(() => _moveNextAsyncMethod()); } public void Reset() { throw new InvalidOperationException("Can not reset an async enumerable."); } } [System.Runtime.CompilerServices.Nullable(0)] private class AsyncEnumerableShapeInfo : IEquatable<AsyncEnumerableShapeInfo> { [CompilerGenerated] protected virtual Type EqualityContract { [CompilerGenerated] get { return typeof(AsyncEnumerableShapeInfo); } } public MethodInfo GetAsyncEnumeratorMethod { get; set; } public PropertyInfo CurrentProperty { get; set; } public MethodInfo MoveNextAsyncMethod { get; set; } public MethodInfo DisposeAsyncMethod { get; set; } public AsyncEnumerableShapeInfo(MethodInfo GetAsyncEnumeratorMethod, PropertyInfo CurrentProperty, MethodInfo MoveNextAsyncMethod, MethodInfo DisposeAsyncMethod) { GetAsyncEnumeratorMethod = GetAsyncEnumeratorMethod; CurrentProperty = CurrentProperty; MoveNextAsyncMethod = MoveNextAsyncMethod; DisposeAsyncMethod = DisposeAsyncMethod; base..ctor(); } [CompilerGenerated] public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("AsyncEnumerableShapeInfo"); stringBuilder.Append(" { "); if (PrintMembers(stringBuilder)) stringBuilder.Append(' '); stringBuilder.Append('}'); return stringBuilder.ToString(); } [CompilerGenerated] protected virtual bool PrintMembers(StringBuilder builder) { RuntimeHelpers.EnsureSufficientExecutionStack(); builder.Append("GetAsyncEnumeratorMethod = "); builder.Append(GetAsyncEnumeratorMethod); builder.Append(", CurrentProperty = "); builder.Append(CurrentProperty); builder.Append(", MoveNextAsyncMethod = "); builder.Append(MoveNextAsyncMethod); builder.Append(", DisposeAsyncMethod = "); builder.Append(DisposeAsyncMethod); return true; } public static bool operator !=(AsyncEnumerableShapeInfo left, AsyncEnumerableShapeInfo right) { return !(left == right); } public static bool operator ==(AsyncEnumerableShapeInfo left, AsyncEnumerableShapeInfo right) { if ((object)left != right) return left?.Equals(right) ?? false; return true; } [CompilerGenerated] public override int GetHashCode() { return (((EqualityComparer<Type>.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<MethodInfo>.Default.GetHashCode(GetAsyncEnumeratorMethod)) * -1521134295 + EqualityComparer<PropertyInfo>.Default.GetHashCode(CurrentProperty)) * -1521134295 + EqualityComparer<MethodInfo>.Default.GetHashCode(MoveNextAsyncMethod)) * -1521134295 + EqualityComparer<MethodInfo>.Default.GetHashCode(DisposeAsyncMethod); } [System.Runtime.CompilerServices.NullableContext(2)] [CompilerGenerated] public override bool Equals(object obj) { return Equals(obj as AsyncEnumerableShapeInfo); } [System.Runtime.CompilerServices.NullableContext(2)] [CompilerGenerated] public virtual bool Equals(AsyncEnumerableShapeInfo other) { if ((object)this != other) { if ((object)other != null && EqualityContract == other.EqualityContract && EqualityComparer<MethodInfo>.Default.Equals(GetAsyncEnumeratorMethod, other.GetAsyncEnumeratorMethod) && EqualityComparer<PropertyInfo>.Default.Equals(CurrentProperty, other.CurrentProperty) && EqualityComparer<MethodInfo>.Default.Equals(MoveNextAsyncMethod, other.MoveNextAsyncMethod)) return EqualityComparer<MethodInfo>.Default.Equals(DisposeAsyncMethod, other.DisposeAsyncMethod); return false; } return true; } [CompilerGenerated] protected AsyncEnumerableShapeInfo(AsyncEnumerableShapeInfo original) { GetAsyncEnumeratorMethod = original.GetAsyncEnumeratorMethod; CurrentProperty = original.CurrentProperty; MoveNextAsyncMethod = original.MoveNextAsyncMethod; DisposeAsyncMethod = original.DisposeAsyncMethod; } [CompilerGenerated] public void Deconstruct(out MethodInfo GetAsyncEnumeratorMethod, out PropertyInfo CurrentProperty, out MethodInfo MoveNextAsyncMethod, out MethodInfo DisposeAsyncMethod) { GetAsyncEnumeratorMethod = this.GetAsyncEnumeratorMethod; CurrentProperty = this.CurrentProperty; MoveNextAsyncMethod = this.MoveNextAsyncMethod; DisposeAsyncMethod = this.DisposeAsyncMethod; } } [System.Runtime.CompilerServices.NullableContext(2)] public static IEnumerable CoalesceToEnumerable(object enumerable) { if (enumerable == null) return null; IEnumerable enumerable2 = enumerable as IEnumerable; if (enumerable2 != null) return enumerable2; if (TryGetAsyncBlockingEnumerable(enumerable, out IEnumerable<object> result)) return result; throw new ArgumentException("Argument can not be converted to an IEnumerable.", "enumerable"); } private static bool TryGetAsyncBlockingEnumerable(object enumerable, [System.Runtime.CompilerServices.Nullable(2)] [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out IEnumerable<object> result) { result = null; Type interface = enumerable.GetType().GetInterface("System.Collections.Generic.IAsyncEnumerable`1"); if ((object)interface == null) return false; MethodInfo method = interface.GetMethod("GetAsyncEnumerator"); if ((object)method == null) return false; Type returnType = method.ReturnType; PropertyInfo property = returnType.GetProperty("Current"); if ((object)property == null) return false; MethodInfo method2 = returnType.GetMethod("MoveNextAsync"); if ((object)method2 == null) return false; Type interface2 = returnType.GetInterface("System.IAsyncDisposable"); if ((object)interface2 == null) return false; MethodInfo method3 = interface2.GetMethod("DisposeAsync"); if ((object)method3 == null) return false; AsyncEnumerableShapeInfo shape = new AsyncEnumerableShapeInfo(method, property, method2, method3); result = new AsyncEnumerableWrapper(shape, enumerable); return true; } } }