tokio/io/util/
empty.rs

1use crate::io::util::poll_proceed_and_make_progress;
2use crate::io::{AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, ReadBuf};
3
4use std::fmt;
5use std::io::{self, SeekFrom};
6use std::pin::Pin;
7use std::task::{ready, Context, Poll};
8
9cfg_io_util! {
10    /// `Empty` ignores any data written via [`AsyncWrite`], and will always be empty
11    /// (returning zero bytes) when read via [`AsyncRead`].
12    ///
13    /// This struct is generally created by calling [`empty`]. Please see
14    /// the documentation of [`empty()`][`empty`] for more details.
15    ///
16    /// This is an asynchronous version of [`std::io::empty`][std].
17    ///
18    /// [`empty`]: fn@empty
19    /// [std]: std::io::empty
20    pub struct Empty {
21        _p: (),
22    }
23
24    /// Creates a value that is always at EOF for reads, and ignores all data written.
25    ///
26    /// All writes on the returned instance will return `Poll::Ready(Ok(buf.len()))`
27    /// and the contents of the buffer will not be inspected.
28    ///
29    /// All reads from the returned instance will return `Poll::Ready(Ok(0))`.
30    ///
31    /// This is an asynchronous version of [`std::io::empty`][std].
32    ///
33    /// [std]: std::io::empty
34    ///
35    /// # Examples
36    ///
37    /// A slightly sad example of not reading anything into a buffer:
38    ///
39    /// ```
40    /// use tokio::io::{self, AsyncReadExt};
41    ///
42    /// #[tokio::main]
43    /// async fn main() {
44    ///     let mut buffer = String::new();
45    ///     io::empty().read_to_string(&mut buffer).await.unwrap();
46    ///     assert!(buffer.is_empty());
47    /// }
48    /// ```
49    ///
50    /// A convoluted way of getting the length of a buffer:
51    ///
52    /// ```
53    /// use tokio::io::{self, AsyncWriteExt};
54    ///
55    /// #[tokio::main]
56    /// async fn main() {
57    ///     let buffer = vec![1, 2, 3, 5, 8];
58    ///     let num_bytes = io::empty().write(&buffer).await.unwrap();
59    ///     assert_eq!(num_bytes, 5);
60    /// }
61    /// ```
62    pub fn empty() -> Empty {
63        Empty { _p: () }
64    }
65}
66
67impl AsyncRead for Empty {
68    #[inline]
69    fn poll_read(
70        self: Pin<&mut Self>,
71        cx: &mut Context<'_>,
72        _: &mut ReadBuf<'_>,
73    ) -> Poll<io::Result<()>> {
74        ready!(crate::trace::trace_leaf(cx));
75        ready!(poll_proceed_and_make_progress(cx));
76        Poll::Ready(Ok(()))
77    }
78}
79
80impl AsyncBufRead for Empty {
81    #[inline]
82    fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
83        ready!(crate::trace::trace_leaf(cx));
84        ready!(poll_proceed_and_make_progress(cx));
85        Poll::Ready(Ok(&[]))
86    }
87
88    #[inline]
89    fn consume(self: Pin<&mut Self>, _: usize) {}
90}
91
92impl AsyncWrite for Empty {
93    #[inline]
94    fn poll_write(
95        self: Pin<&mut Self>,
96        cx: &mut Context<'_>,
97        buf: &[u8],
98    ) -> Poll<io::Result<usize>> {
99        ready!(crate::trace::trace_leaf(cx));
100        ready!(poll_proceed_and_make_progress(cx));
101        Poll::Ready(Ok(buf.len()))
102    }
103
104    #[inline]
105    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
106        ready!(crate::trace::trace_leaf(cx));
107        ready!(poll_proceed_and_make_progress(cx));
108        Poll::Ready(Ok(()))
109    }
110
111    #[inline]
112    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
113        ready!(crate::trace::trace_leaf(cx));
114        ready!(poll_proceed_and_make_progress(cx));
115        Poll::Ready(Ok(()))
116    }
117
118    #[inline]
119    fn is_write_vectored(&self) -> bool {
120        true
121    }
122
123    #[inline]
124    fn poll_write_vectored(
125        self: Pin<&mut Self>,
126        cx: &mut Context<'_>,
127        bufs: &[io::IoSlice<'_>],
128    ) -> Poll<Result<usize, io::Error>> {
129        ready!(crate::trace::trace_leaf(cx));
130        ready!(poll_proceed_and_make_progress(cx));
131        let num_bytes = bufs.iter().map(|b| b.len()).sum();
132        Poll::Ready(Ok(num_bytes))
133    }
134}
135
136impl AsyncSeek for Empty {
137    #[inline]
138    fn start_seek(self: Pin<&mut Self>, _position: SeekFrom) -> io::Result<()> {
139        Ok(())
140    }
141
142    #[inline]
143    fn poll_complete(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<u64>> {
144        ready!(crate::trace::trace_leaf(cx));
145        ready!(poll_proceed_and_make_progress(cx));
146        Poll::Ready(Ok(0))
147    }
148}
149
150impl fmt::Debug for Empty {
151    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152        f.pad("Empty { .. }")
153    }
154}
155
156#[cfg(test)]
157mod tests {
158    use super::*;
159
160    #[test]
161    fn assert_unpin() {
162        crate::is_unpin::<Empty>();
163    }
164}