using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
namespace Acp;
///
/// An in-process transport pair joined by two channels. returns the two
/// ends of one connection, used to wire a ClientSideConnection directly to an
/// AgentSideConnection with no subprocess (tests, in-proc agents).
///
public sealed class InMemoryTransport : IAcpTransport
{
private ChannelReader Incoming { get; }
private ChannelWriter Outgoing { get; }
private InMemoryTransport(ChannelReader incoming, ChannelWriter outgoing)
{
Incoming = incoming;
Outgoing = outgoing;
}
/// Creates the two connected ends of a single in-memory link.
public static (IAcpTransport A, IAcpTransport B) CreatePair()
{
Channel aToB = Channel.CreateUnbounded();
Channel bToA = Channel.CreateUnbounded();
InMemoryTransport a = new(bToA.Reader, aToB.Writer);
InMemoryTransport b = new(aToB.Reader, bToA.Writer);
return (a, b);
}
public async ValueTask ReadLineAsync(CancellationToken cancellationToken = default)
{
try
{
return await Incoming.ReadAsync(cancellationToken).ConfigureAwait(false);
}
catch (ChannelClosedException)
{
return null;
}
}
public ValueTask WriteLineAsync(string json, CancellationToken cancellationToken = default) =>
Outgoing.WriteAsync(json, cancellationToken);
public void Dispose() => Outgoing.TryComplete();
}