using AyCode.Core.Serializers.Binaries;
using System;
using System.IO.Pipelines;
using System.Threading;
using System.Threading.Tasks;
namespace AyCode.Core.Tests.Serialization;
///
/// Test/benchmark-only extension methods for populating
/// from -backed transports (NamedPipe, FileStream,
/// custom pipe sources).
///
/// Why test-only: in real production, the consuming application already has its own
/// reader-task that reads from the pipe and pushes bytes via AsyncPipeReaderInput.Feed
/// — providing this drain extension publicly would duplicate that responsibility and confuse
/// the canonical push-pattern. The extension is kept here for unit-test scaffolding and the
/// streaming benchmark; production NuGet consumers should write their own drain logic in their
/// own reader-task following the application's threading model.
///
public static class AsyncPipeReaderInputExtensions
{
///
/// Drains a end-to-end into the :
/// calls on each segment and
/// when the pipe completes.
///
/// Typical usage (test-only): NamedPipe IPC and FileStream-via-PipeReader transports
/// schedule this on a background task while the deserialization context reads from the same
/// input on another thread.
///
/// is invoked in a finally block —
/// ensures the consumer always wakes up even if the pipe read throws or the operation is
/// cancelled. Exceptions (including ) propagate to
/// the caller after Complete runs.
///
/// The receive-side input to feed.
/// The pipe reader to drain.
/// Optional cancellation token.
/// If or is null.
public static async Task DrainFromAsync(this AsyncPipeReaderInput input, PipeReader reader, CancellationToken cancellationToken = default)
{
if (input is null) throw new ArgumentNullException(nameof(input));
if (reader is null) throw new ArgumentNullException(nameof(reader));
try
{
while (true)
{
var result = await reader.ReadAsync(cancellationToken).ConfigureAwait(false);
foreach (var segment in result.Buffer) input.Feed(segment.Span);
reader.AdvanceTo(result.Buffer.End);
if (result.IsCompleted) break;
}
}
finally
{
input.Complete();
}
}
}