1mod boxed;
2
3use futures::{AsyncRead, AsyncWrite};
4use std::{
5 pin::Pin,
6 task::{Context, Poll},
7};
8
9pub use boxed::{StreamMuxerBox, SubstreamBox};
10
11pub trait StreamMuxer {
12 type Substream: AsyncRead + AsyncWrite;
13 type Error: std::error::Error;
14
15 fn poll_inbound(
17 self: Pin<&mut Self>,
18 cx: &mut Context<'_>,
19 ) -> Poll<Result<Self::Substream, Self::Error>>;
20
21 fn poll_outbound(
23 self: Pin<&mut Self>,
24 cx: &mut Context<'_>,
25 ) -> Poll<Result<Self::Substream, Self::Error>>;
26
27 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
29
30 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
32}
33
34pub trait StreamMuxerExt: StreamMuxer + Sized {
35 fn poll_inbound_unpin(
36 &mut self,
37 cx: &mut Context<'_>,
38 ) -> Poll<Result<Self::Substream, Self::Error>>
39 where
40 Self: Unpin,
41 {
42 Pin::new(self).poll_inbound(cx)
43 }
44
45 fn poll_outbound_unpin(
46 &mut self,
47 cx: &mut Context<'_>,
48 ) -> Poll<Result<Self::Substream, Self::Error>>
49 where
50 Self: Unpin,
51 {
52 Pin::new(self).poll_outbound(cx)
53 }
54
55 fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>
56 where
57 Self: Unpin,
58 {
59 Pin::new(self).poll(cx)
60 }
61
62 fn poll_close_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>
63 where
64 Self: Unpin,
65 {
66 Pin::new(self).poll_close(cx)
67 }
68
69 fn close(self) -> Closing<Self> {
70 Closing(self)
71 }
72}
73
74impl<S> StreamMuxerExt for S where S: StreamMuxer {}
75
76pub struct Closing<S>(S);
77
78impl<S> Future for Closing<S>
79where
80 S: StreamMuxer + Unpin,
81{
82 type Output = Result<(), S::Error>;
83
84 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
85 self.0.poll_close_unpin(cx)
86 }
87}