1mod bounds;
7
8use std::future::Future;
9
10pub use crate::bounds::{MaybeSend, MaybeSync};
11use bytes::{Buf, BufMut, Bytes, BytesMut};
12
13pub trait Error: std::error::Error + MaybeSend + MaybeSync + 'static {
17 fn session_error(&self) -> Option<(u32, String)>;
21
22 fn stream_error(&self) -> Option<u32> {
24 None
25 }
26}
27
28pub trait Session: Clone + MaybeSend + MaybeSync + 'static {
33 type SendStream: SendStream;
35 type RecvStream: RecvStream;
37 type Error: Error;
39
40 fn accept_uni(&self)
42 -> impl Future<Output = Result<Self::RecvStream, Self::Error>> + MaybeSend;
43
44 fn accept_bi(
46 &self,
47 ) -> impl Future<Output = Result<(Self::SendStream, Self::RecvStream), Self::Error>> + MaybeSend;
48
49 fn open_bi(
51 &self,
52 ) -> impl Future<Output = Result<(Self::SendStream, Self::RecvStream), Self::Error>> + MaybeSend;
53
54 fn open_uni(&self) -> impl Future<Output = Result<Self::SendStream, Self::Error>> + MaybeSend;
56
57 fn send_datagram(
67 &self,
68 payload: Bytes,
69 ) -> impl Future<Output = Result<(), Self::Error>> + MaybeSend;
70
71 fn recv_datagram(&self) -> impl Future<Output = Result<Bytes, Self::Error>> + MaybeSend;
73
74 fn max_datagram_size(&self) -> usize;
76
77 fn close(&self, code: u32, reason: &str);
79
80 fn closed(&self) -> impl Future<Output = Self::Error> + MaybeSend;
82}
83
84pub trait SendStream: MaybeSend {
89 type Error: Error;
91
92 fn write(&mut self, buf: &[u8])
96 -> impl Future<Output = Result<usize, Self::Error>> + MaybeSend;
97
98 fn write_buf<B: Buf + MaybeSend>(
100 &mut self,
101 buf: &mut B,
102 ) -> impl Future<Output = Result<usize, Self::Error>> + MaybeSend {
103 async move {
104 let chunk = buf.chunk();
105 let size = self.write(chunk).await?;
106 assert!(
107 size > 0 || chunk.is_empty(),
108 "SendStream::write returned zero for a non-empty buffer"
109 );
110 assert!(
111 size <= chunk.len(),
112 "SendStream::write returned more bytes than provided"
113 );
114 buf.advance(size);
115 Ok(size)
116 }
117 }
118
119 fn write_chunk(
121 &mut self,
122 chunk: Bytes,
123 ) -> impl Future<Output = Result<(), Self::Error>> + MaybeSend {
124 async move {
125 let mut c = chunk;
126 self.write_all_buf(&mut c).await
127 }
128 }
129
130 fn write_all(
132 &mut self,
133 buf: &[u8],
134 ) -> impl Future<Output = Result<(), Self::Error>> + MaybeSend {
135 async move {
136 let mut pos = 0;
137 while pos < buf.len() {
138 let written = self.write(&buf[pos..]).await?;
139 assert!(
140 written > 0,
141 "SendStream::write returned zero for a non-empty buffer"
142 );
143 assert!(
144 written <= buf.len() - pos,
145 "SendStream::write returned more bytes than provided"
146 );
147 pos += written;
148 }
149 Ok(())
150 }
151 }
152
153 fn write_all_buf<B: Buf + MaybeSend>(
155 &mut self,
156 buf: &mut B,
157 ) -> impl Future<Output = Result<(), Self::Error>> + MaybeSend {
158 async move {
159 while buf.has_remaining() {
160 let written = self.write_buf(buf).await?;
161 assert!(
162 written > 0,
163 "SendStream::write returned zero for a non-empty buffer"
164 );
165 }
166 Ok(())
167 }
168 }
169
170 fn set_priority(&mut self, order: u8);
174
175 fn finish(&mut self) -> Result<(), Self::Error>;
183
184 fn reset(&mut self, code: u32);
189
190 fn closed(&mut self) -> impl Future<Output = Result<(), Self::Error>> + MaybeSend;
201}
202
203pub trait RecvStream: MaybeSend {
208 type Error: Error;
210
211 fn read(
215 &mut self,
216 dst: &mut [u8],
217 ) -> impl Future<Output = Result<Option<usize>, Self::Error>> + MaybeSend;
218
219 fn read_buf<B: BufMut + MaybeSend>(
224 &mut self,
225 buf: &mut B,
226 ) -> impl Future<Output = Result<Option<usize>, Self::Error>> + MaybeSend {
227 async move {
228 let capacity = buf.chunk_mut().len().min(8 * 1024);
231 if capacity == 0 {
232 return Ok(Some(0));
233 }
234 let mut dst = vec![0; capacity];
235 let size = match self.read(&mut dst).await? {
236 Some(size) => size,
237 None => return Ok(None),
238 };
239 assert!(
240 size <= dst.len(),
241 "RecvStream::read returned more bytes than the provided buffer"
242 );
243 buf.put_slice(&dst[..size]);
244
245 Ok(Some(size))
246 }
247 }
248
249 fn read_chunk(
253 &mut self,
254 max: usize,
255 ) -> impl Future<Output = Result<Option<Bytes>, Self::Error>> + MaybeSend {
256 async move {
257 let mut buf = BytesMut::with_capacity(max.min(8 * 1024));
259
260 Ok(self.read_buf(&mut buf).await?.map(|_| buf.freeze()))
261 }
262 }
263
264 fn stop(&mut self, code: u32);
269
270 fn closed(&mut self) -> impl Future<Output = Result<(), Self::Error>> + MaybeSend;
277
278 fn read_all(&mut self) -> impl Future<Output = Result<Bytes, Self::Error>> + MaybeSend {
280 async move {
281 let mut buf = BytesMut::new();
282 self.read_all_buf(&mut buf).await?;
283 Ok(buf.freeze())
284 }
285 }
286
287 fn read_all_buf<B: BufMut + MaybeSend>(
289 &mut self,
290 buf: &mut B,
291 ) -> impl Future<Output = Result<usize, Self::Error>> + MaybeSend {
292 async move {
293 let mut size = 0;
294 while buf.has_remaining_mut() {
295 match self.read_buf(buf).await? {
296 Some(n) => size += n,
297 None => break,
298 }
299 }
300 Ok(size)
301 }
302 }
303}
304
305#[cfg(test)]
306mod tests {
307 use super::{Error, RecvStream, SendStream};
308 use bytes::{Bytes, BytesMut};
309 use futures::executor::block_on;
310 use std::fmt;
311
312 #[derive(Debug)]
313 struct TestError;
314
315 impl fmt::Display for TestError {
316 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
317 write!(f, "test error")
318 }
319 }
320
321 impl std::error::Error for TestError {}
322
323 impl Error for TestError {
324 fn session_error(&self) -> Option<(u32, String)> {
325 None
326 }
327 }
328
329 struct TestRecvStream {
330 data: Vec<u8>,
331 pos: usize,
332 }
333
334 impl TestRecvStream {
335 fn new(data: &[u8]) -> Self {
336 Self {
337 data: data.to_vec(),
338 pos: 0,
339 }
340 }
341 }
342
343 impl RecvStream for TestRecvStream {
344 type Error = TestError;
345
346 async fn read(&mut self, dst: &mut [u8]) -> Result<Option<usize>, Self::Error> {
347 let available = self.data.len().saturating_sub(self.pos);
348 if available == 0 {
349 return Ok(None);
350 }
351
352 let size = available.min(dst.len());
353 let end = self.pos + size;
354 dst[..size].copy_from_slice(&self.data[self.pos..end]);
355 self.pos = end;
356
357 Ok(Some(size))
358 }
359
360 fn stop(&mut self, _code: u32) {}
361
362 async fn closed(&mut self) -> Result<(), Self::Error> {
363 Ok(())
364 }
365 }
366
367 struct PartialSendStream {
368 data: Vec<u8>,
369 max_write: usize,
370 }
371
372 impl SendStream for PartialSendStream {
373 type Error = TestError;
374
375 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
376 let size = buf.len().min(self.max_write);
377 self.data.extend_from_slice(&buf[..size]);
378 Ok(size)
379 }
380
381 fn set_priority(&mut self, _order: u8) {}
382
383 fn finish(&mut self) -> Result<(), Self::Error> {
384 Ok(())
385 }
386
387 fn reset(&mut self, _code: u32) {}
388
389 async fn closed(&mut self) -> Result<(), Self::Error> {
390 Ok(())
391 }
392 }
393
394 #[test]
395 fn read_chunk_respects_max_and_eof() {
396 let mut stream = TestRecvStream::new(b"hello world");
397
398 let first = block_on(stream.read_chunk(5)).unwrap().unwrap();
399 assert_eq!(first, Bytes::from_static(b"hello"));
400
401 let second = block_on(stream.read_chunk(1024)).unwrap().unwrap();
402 assert_eq!(second, Bytes::from_static(b" world"));
403
404 let end = block_on(stream.read_chunk(1)).unwrap();
405 assert!(end.is_none());
406 }
407
408 #[test]
409 fn read_buf_advances_buffer() {
410 let mut stream = TestRecvStream::new(b"test");
411 let mut buf = BytesMut::with_capacity(4);
412
413 let size = block_on(stream.read_buf(&mut buf)).unwrap().unwrap();
414 assert_eq!(size, 4);
415 assert_eq!(&buf[..], b"test");
416 }
417
418 #[test]
419 fn write_chunk_retries_partial_writes() {
420 let mut stream = PartialSendStream {
421 data: Vec::new(),
422 max_write: 2,
423 };
424
425 block_on(stream.write_chunk(Bytes::from_static(b"hello"))).unwrap();
426 assert_eq!(stream.data, b"hello");
427 }
428}