1use crate::io::util::poll_proceed_and_make_progress;
2use crate::io::{AsyncBufRead, AsyncRead, AsyncWrite, ReadBuf};
3
4use std::fmt;
5use std::io;
6use std::pin::Pin;
7use std::task::{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 fmt::Debug for Empty {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 f.pad("Empty { .. }")
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145
146 #[test]
147 fn assert_unpin() {
148 crate::is_unpin::<Empty>();
149 }
150}
151