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