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(); }