1 #[cfg_attr(not(feature = "all-implementations"), allow(unused))]
2 use std::{
3     io::Result,
4     pin::Pin,
5     task::{Context, Poll},
6 };
7 
8 pub struct TrackClosed<W> {
9     inner: W,
10     closed: bool,
11 }
12 
13 impl<W> TrackClosed<W> {
new(inner: W) -> Self14     pub fn new(inner: W) -> Self {
15         Self {
16             inner,
17             closed: false,
18         }
19     }
20 
is_closed(&self) -> bool21     pub fn is_closed(&self) -> bool {
22         self.closed
23     }
24 }
25 
26 #[cfg(feature = "futures-io")]
27 impl<W: futures::io::AsyncWrite + Unpin> futures::io::AsyncWrite for TrackClosed<W> {
poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>>28     fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>> {
29         assert!(!self.closed);
30         Pin::new(&mut self.inner).poll_write(cx, buf)
31     }
32 
poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>>33     fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>> {
34         assert!(!self.closed);
35         Pin::new(&mut self.inner).poll_flush(cx)
36     }
37 
poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>>38     fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>> {
39         assert!(!self.closed);
40         match Pin::new(&mut self.inner).poll_close(cx) {
41             Poll::Ready(Ok(())) => {
42                 self.closed = true;
43                 Poll::Ready(Ok(()))
44             }
45             other => other,
46         }
47     }
48 
poll_write_vectored( mut self: Pin<&mut Self>, cx: &mut Context, bufs: &[std::io::IoSlice], ) -> Poll<Result<usize>>49     fn poll_write_vectored(
50         mut self: Pin<&mut Self>,
51         cx: &mut Context,
52         bufs: &[std::io::IoSlice],
53     ) -> Poll<Result<usize>> {
54         assert!(!self.closed);
55         Pin::new(&mut self.inner).poll_write_vectored(cx, bufs)
56     }
57 }
58 
59 #[cfg(feature = "tokio-02")]
60 impl<W: tokio_02::io::AsyncWrite + Unpin> tokio_02::io::AsyncWrite for TrackClosed<W> {
poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>>61     fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>> {
62         assert!(!self.closed);
63         Pin::new(&mut self.inner).poll_write(cx, buf)
64     }
65 
poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>>66     fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>> {
67         assert!(!self.closed);
68         Pin::new(&mut self.inner).poll_flush(cx)
69     }
70 
poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>>71     fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>> {
72         assert!(!self.closed);
73         match Pin::new(&mut self.inner).poll_shutdown(cx) {
74             Poll::Ready(Ok(())) => {
75                 self.closed = true;
76                 Poll::Ready(Ok(()))
77             }
78             other => other,
79         }
80     }
81 }
82 
83 #[cfg(feature = "tokio-03")]
84 impl<W: tokio_03::io::AsyncWrite + Unpin> tokio_03::io::AsyncWrite for TrackClosed<W> {
poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>>85     fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>> {
86         assert!(!self.closed);
87         Pin::new(&mut self.inner).poll_write(cx, buf)
88     }
89 
poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>>90     fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>> {
91         assert!(!self.closed);
92         Pin::new(&mut self.inner).poll_flush(cx)
93     }
94 
poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>>95     fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>> {
96         assert!(!self.closed);
97         match Pin::new(&mut self.inner).poll_shutdown(cx) {
98             Poll::Ready(Ok(())) => {
99                 self.closed = true;
100                 Poll::Ready(Ok(()))
101             }
102             other => other,
103         }
104     }
105 }
106 
107 #[cfg(feature = "tokio")]
108 impl<W: tokio::io::AsyncWrite + Unpin> tokio::io::AsyncWrite for TrackClosed<W> {
poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>>109     fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>> {
110         assert!(!self.closed);
111         Pin::new(&mut self.inner).poll_write(cx, buf)
112     }
113 
poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>>114     fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>> {
115         assert!(!self.closed);
116         Pin::new(&mut self.inner).poll_flush(cx)
117     }
118 
poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>>119     fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<()>> {
120         assert!(!self.closed);
121         match Pin::new(&mut self.inner).poll_shutdown(cx) {
122             Poll::Ready(Ok(())) => {
123                 self.closed = true;
124                 Poll::Ready(Ok(()))
125             }
126             other => other,
127         }
128     }
129 }
130