moqtap_client/transport/
mod.rs1pub mod quic;
7#[cfg(feature = "webtransport")]
8pub mod webtransport;
9
10use bytes::Bytes;
11
12#[derive(Debug, thiserror::Error)]
14pub enum TransportError {
15 #[error("connection error: {0}")]
17 Connection(String),
18 #[error("write error: {0}")]
20 Write(String),
21 #[error("read error: {0}")]
23 Read(String),
24 #[error("stream closed")]
26 StreamClosed,
27 #[error("send datagram error: {0}")]
29 SendDatagram(String),
30 #[error("connection lost")]
32 ConnectionLost,
33 #[error("connect error: {0}")]
35 Connect(String),
36}
37
38pub enum Transport {
40 Quic(quic::QuicTransport),
42 #[cfg(feature = "webtransport")]
44 WebTransport(webtransport::WebTransportTransport),
45}
46
47impl Transport {
48 pub async fn open_bi(&self) -> Result<(SendStream, RecvStream), TransportError> {
50 match self {
51 Transport::Quic(t) => t.open_bi().await,
52 #[cfg(feature = "webtransport")]
53 Transport::WebTransport(t) => t.open_bi().await,
54 }
55 }
56
57 pub async fn accept_bi(&self) -> Result<(SendStream, RecvStream), TransportError> {
59 match self {
60 Transport::Quic(t) => t.accept_bi().await,
61 #[cfg(feature = "webtransport")]
62 Transport::WebTransport(t) => t.accept_bi().await,
63 }
64 }
65
66 pub async fn open_uni(&self) -> Result<SendStream, TransportError> {
68 match self {
69 Transport::Quic(t) => t.open_uni().await,
70 #[cfg(feature = "webtransport")]
71 Transport::WebTransport(t) => t.open_uni().await,
72 }
73 }
74
75 pub async fn accept_uni(&self) -> Result<RecvStream, TransportError> {
77 match self {
78 Transport::Quic(t) => t.accept_uni().await,
79 #[cfg(feature = "webtransport")]
80 Transport::WebTransport(t) => t.accept_uni().await,
81 }
82 }
83
84 pub fn send_datagram(&self, data: Bytes) -> Result<(), TransportError> {
86 match self {
87 Transport::Quic(t) => t.send_datagram(data),
88 #[cfg(feature = "webtransport")]
89 Transport::WebTransport(t) => t.send_datagram(data),
90 }
91 }
92
93 pub async fn recv_datagram(&self) -> Result<Bytes, TransportError> {
95 match self {
96 Transport::Quic(t) => t.recv_datagram().await,
97 #[cfg(feature = "webtransport")]
98 Transport::WebTransport(t) => t.recv_datagram().await,
99 }
100 }
101
102 pub fn close(&self, code: u32, reason: &[u8]) {
104 match self {
105 Transport::Quic(t) => t.close(code, reason),
106 #[cfg(feature = "webtransport")]
107 Transport::WebTransport(t) => t.close(code, reason),
108 }
109 }
110}
111
112pub enum SendStream {
114 Quic(quinn::SendStream),
116 #[cfg(feature = "webtransport")]
118 WebTransport(webtransport::WtSendStream),
119}
120
121impl SendStream {
122 pub fn stream_id(&self) -> u64 {
124 match self {
125 SendStream::Quic(s) => s.id().index(),
126 #[cfg(feature = "webtransport")]
127 SendStream::WebTransport(_) => 0, }
129 }
130
131 pub async fn write_all(&mut self, buf: &[u8]) -> Result<(), TransportError> {
133 match self {
134 SendStream::Quic(s) => {
135 s.write_all(buf).await.map_err(|e| TransportError::Write(e.to_string()))
136 }
137 #[cfg(feature = "webtransport")]
138 SendStream::WebTransport(s) => s.write_all(buf).await,
139 }
140 }
141
142 pub fn finish(&mut self) -> Result<(), TransportError> {
144 match self {
145 SendStream::Quic(s) => {
146 s.finish().map_err(|_| TransportError::StreamClosed)?;
147 Ok(())
148 }
149 #[cfg(feature = "webtransport")]
150 SendStream::WebTransport(s) => s.finish(),
151 }
152 }
153}
154
155pub enum RecvStream {
157 Quic(quinn::RecvStream),
159 #[cfg(feature = "webtransport")]
161 WebTransport(webtransport::WtRecvStream),
162}
163
164impl RecvStream {
165 pub fn stream_id(&self) -> u64 {
167 match self {
168 RecvStream::Quic(s) => s.id().index(),
169 #[cfg(feature = "webtransport")]
170 RecvStream::WebTransport(_) => 0,
171 }
172 }
173
174 pub async fn read(&mut self, buf: &mut [u8]) -> Result<Option<usize>, TransportError> {
177 match self {
178 RecvStream::Quic(s) => {
179 s.read(buf).await.map_err(|e| TransportError::Read(e.to_string()))
180 }
181 #[cfg(feature = "webtransport")]
182 RecvStream::WebTransport(s) => s.read(buf).await,
183 }
184 }
185}