IAsyncEnumerableOfTConverter<TAsyncEnumerable, TElement>
sealed class IAsyncEnumerableOfTConverter<TAsyncEnumerable, TElement> : JsonCollectionConverter<TAsyncEnumerable, TElement> where TAsyncEnumerable : IAsyncEnumerable<TElement>
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace System.Text.Json.Serialization.Converters
{
internal sealed class IAsyncEnumerableOfTConverter<TAsyncEnumerable, TElement> : JsonCollectionConverter<TAsyncEnumerable, TElement> where TAsyncEnumerable : IAsyncEnumerable<TElement>
{
private sealed class BufferedAsyncEnumerable : IAsyncEnumerable<TElement>
{
public readonly List<TElement> _buffer = new List<TElement>();
[AsyncIteratorStateMachine(typeof(IAsyncEnumerableOfTConverter<, >.BufferedAsyncEnumerable.<GetAsyncEnumerator>d__1))]
public IAsyncEnumerator<TElement> GetAsyncEnumerator(CancellationToken _)
{
<GetAsyncEnumerator>d__1 <GetAsyncEnumerator>d__ = new <GetAsyncEnumerator>d__1(-3);
<GetAsyncEnumerator>d__.<>4__this = this;
return <GetAsyncEnumerator>d__;
}
}
internal override bool SupportsCreateObjectDelegate => false;
internal override bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options, [System.Runtime.CompilerServices.ScopedRef] ref ReadStack state, out TAsyncEnumerable value)
{
if (!typeToConvert.IsAssignableFrom(typeof(IAsyncEnumerable<TElement>)))
ThrowHelper.ThrowNotSupportedException_CannotPopulateCollection(Type, ref reader, ref state);
return base.OnTryRead(ref reader, typeToConvert, options, ref state, out value);
}
protected override void Add([In] [System.Runtime.CompilerServices.IsReadOnly] TElement value, ref ReadStack state)
{
((BufferedAsyncEnumerable)state.Current.ReturnValue)._buffer.Add(value);
}
protected override void CreateCollection(ref Utf8JsonReader reader, [System.Runtime.CompilerServices.ScopedRef] ref ReadStack state, JsonSerializerOptions options)
{
state.Current.ReturnValue = new BufferedAsyncEnumerable();
}
internal override bool OnTryWrite(Utf8JsonWriter writer, TAsyncEnumerable value, JsonSerializerOptions options, ref WriteStack state)
{
if (!state.SupportAsync)
ThrowHelper.ThrowNotSupportedException_TypeRequiresAsyncSerialization(Type);
return base.OnTryWrite(writer, value, options, ref state);
}
protected override bool OnWriteResume(Utf8JsonWriter writer, TAsyncEnumerable value, JsonSerializerOptions options, ref WriteStack state)
{
IAsyncEnumerator<TElement> asyncEnumerator;
ValueTask<bool> valueTask;
if (state.Current.AsyncDisposable == null) {
asyncEnumerator = value.GetAsyncEnumerator(state.CancellationToken);
state.Current.AsyncDisposable = asyncEnumerator;
valueTask = asyncEnumerator.MoveNextAsync();
if (!valueTask.IsCompleted) {
state.SuppressFlush = true;
goto IL_0106;
}
} else {
asyncEnumerator = (IAsyncEnumerator<TElement>)state.Current.AsyncDisposable;
if (!state.Current.AsyncEnumeratorIsPendingCompletion)
valueTask = new ValueTask<bool>(true);
else {
valueTask = new ValueTask<bool>((Task<bool>)state.PendingTask);
state.Current.AsyncEnumeratorIsPendingCompletion = false;
state.PendingTask = null;
}
}
JsonConverter<TElement> elementConverter = JsonCollectionConverter<TAsyncEnumerable, TElement>.GetElementConverter(ref state);
do {
if (!valueTask.Result) {
state.Current.AsyncDisposable = null;
state.AddCompletedAsyncDisposable(asyncEnumerator);
return true;
}
if (JsonConverter.ShouldFlush(ref state, writer))
return false;
TElement value2 = asyncEnumerator.Current;
if (!elementConverter.TryWrite(writer, ref value2, options, ref state))
return false;
state.Current.EndCollectionElement();
valueTask = asyncEnumerator.MoveNextAsync();
} while (valueTask.IsCompleted);
goto IL_0106;
IL_0106:
state.PendingTask = valueTask.AsTask();
state.Current.AsyncEnumeratorIsPendingCompletion = true;
return false;
}
}
}