1 use crate::io::util::poll_proceed_and_make_progress;
2 use crate::io::AsyncWrite;
3 
4 use std::fmt;
5 use std::io;
6 use std::pin::Pin;
7 use std::task::{ready, Context, Poll};
8 
9 cfg_io_util! {
10     /// An async writer which will move data into the void.
11     ///
12     /// This struct is generally created by calling [`sink`][sink]. Please
13     /// see the documentation of `sink()` for more details.
14     ///
15     /// This is an asynchronous version of [`std::io::Sink`][std].
16     ///
17     /// [sink]: sink()
18     /// [std]: std::io::Sink
19     pub struct Sink {
20         _p: (),
21     }
22 
23     /// Creates an instance of an async writer which will successfully consume all
24     /// data.
25     ///
26     /// All calls to [`poll_write`] on the returned instance will return
27     /// `Poll::Ready(Ok(buf.len()))` and the contents of the buffer will not be
28     /// inspected.
29     ///
30     /// This is an asynchronous version of [`std::io::sink`][std].
31     ///
32     /// [`poll_write`]: crate::io::AsyncWrite::poll_write()
33     /// [std]: std::io::sink
34     ///
35     /// # Examples
36     ///
37     /// ```
38     /// use tokio::io::{self, AsyncWriteExt};
39     ///
40     /// #[tokio::main]
41     /// async fn main() -> io::Result<()> {
42     ///     let buffer = vec![1, 2, 3, 5, 8];
43     ///     let num_bytes = io::sink().write(&buffer).await?;
44     ///     assert_eq!(num_bytes, 5);
45     ///     Ok(())
46     /// }
47     /// ```
48     pub fn sink() -> Sink {
49         Sink { _p: () }
50     }
51 }
52 
53 impl AsyncWrite for Sink {
54     #[inline]
poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<Result<usize, io::Error>>55     fn poll_write(
56         self: Pin<&mut Self>,
57         cx: &mut Context<'_>,
58         buf: &[u8],
59     ) -> Poll<Result<usize, io::Error>> {
60         ready!(crate::trace::trace_leaf(cx));
61         ready!(poll_proceed_and_make_progress(cx));
62         Poll::Ready(Ok(buf.len()))
63     }
64 
65     #[inline]
poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>>66     fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
67         ready!(crate::trace::trace_leaf(cx));
68         ready!(poll_proceed_and_make_progress(cx));
69         Poll::Ready(Ok(()))
70     }
71 
72     #[inline]
poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>>73     fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
74         ready!(crate::trace::trace_leaf(cx));
75         ready!(poll_proceed_and_make_progress(cx));
76         Poll::Ready(Ok(()))
77     }
78 }
79 
80 impl fmt::Debug for Sink {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result81     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82         f.pad("Sink { .. }")
83     }
84 }
85 
86 #[cfg(test)]
87 mod tests {
88     use super::*;
89 
90     #[test]
assert_unpin()91     fn assert_unpin() {
92         crate::is_unpin::<Sink>();
93     }
94 }
95