Skip to main content

runsync_transfer/transport/
mod.rs

1//! Transport abstraction.
2//!
3//! The engine needs exactly four things from a connection: open and accept
4//! unidirectional streams (data), and open and accept a bidirectional stream
5//! (control). Anything providing those can carry a transfer — QUIC is the
6//! intended target, but the in-memory transport used by the test suite
7//! implements the same trait, and so can an existing connection you already
8//! own.
9//!
10//! This is deliberately a `dyn`-compatible trait taking `Box`ed streams. The
11//! per-call cost is one virtual dispatch per *stream*, not per chunk, so it is
12//! invisible next to the I/O — and in exchange a host application can hand the
13//! engine its own live `quinn::Connection` instead of letting the engine dial
14//! its own.
15
16use crate::error::Result;
17use tokio::io::{AsyncRead, AsyncWrite};
18
19pub mod mem;
20#[cfg(feature = "quic")]
21pub mod quic;
22
23/// Write half of a stream. Call `shutdown()` to signal a clean end of stream.
24pub type BoxSend = Box<dyn AsyncWrite + Unpin + Send>;
25/// Read half of a stream. Returns EOF when the peer finished it.
26pub type BoxRecv = Box<dyn AsyncRead + Unpin + Send>;
27
28#[async_trait::async_trait]
29pub trait Transport: Send + Sync + 'static {
30    /// Open a unidirectional stream for data frames.
31    async fn open_uni(&self) -> Result<BoxSend>;
32
33    /// Accept the next unidirectional stream the peer opened.
34    async fn accept_uni(&self) -> Result<BoxRecv>;
35
36    /// Open the bidirectional control stream.
37    async fn open_bi(&self) -> Result<(BoxSend, BoxRecv)>;
38
39    /// Accept the peer's bidirectional control stream.
40    async fn accept_bi(&self) -> Result<(BoxSend, BoxRecv)>;
41
42    /// Close the connection. Best-effort; never blocks.
43    fn close(&self, code: u32, reason: &[u8]);
44
45    /// Human-readable peer identity, for logs.
46    fn peer_label(&self) -> String {
47        "peer".to_string()
48    }
49
50    /// Bytes already sent on this connection, if the transport tracks it.
51    /// Used to report true wire throughput against post-compression volume.
52    fn bytes_sent(&self) -> Option<u64> {
53        None
54    }
55}