1 | use crate::io::{AsyncBufRead, AsyncRead, ReadBuf}; |
2 | |
3 | use std::fmt; |
4 | use std::io; |
5 | use std::pin::Pin; |
6 | use std::task::{Context, Poll}; |
7 | |
8 | cfg_io_util! { |
9 | /// An async reader which is always at EOF. |
10 | /// |
11 | /// This struct is generally created by calling [`empty`]. Please see |
12 | /// the documentation of [`empty()`][`empty`] for more details. |
13 | /// |
14 | /// This is an asynchronous version of [`std::io::empty`][std]. |
15 | /// |
16 | /// [`empty`]: fn@empty |
17 | /// [std]: std::io::empty |
18 | pub struct Empty { |
19 | _p: (), |
20 | } |
21 | |
22 | /// Creates a new empty async reader. |
23 | /// |
24 | /// All reads from the returned reader will return `Poll::Ready(Ok(0))`. |
25 | /// |
26 | /// This is an asynchronous version of [`std::io::empty`][std]. |
27 | /// |
28 | /// [std]: std::io::empty |
29 | /// |
30 | /// # Examples |
31 | /// |
32 | /// A slightly sad example of not reading anything into a buffer: |
33 | /// |
34 | /// ``` |
35 | /// use tokio::io::{self, AsyncReadExt}; |
36 | /// |
37 | /// #[tokio::main] |
38 | /// async fn main() { |
39 | /// let mut buffer = String::new(); |
40 | /// io::empty().read_to_string(&mut buffer).await.unwrap(); |
41 | /// assert!(buffer.is_empty()); |
42 | /// } |
43 | /// ``` |
44 | pub fn empty() -> Empty { |
45 | Empty { _p: () } |
46 | } |
47 | } |
48 | |
49 | impl AsyncRead for Empty { |
50 | #[inline ] |
51 | fn poll_read( |
52 | self: Pin<&mut Self>, |
53 | cx: &mut Context<'_>, |
54 | _: &mut ReadBuf<'_>, |
55 | ) -> Poll<io::Result<()>> { |
56 | ready!(crate::trace::trace_leaf(cx)); |
57 | ready!(poll_proceed_and_make_progress(cx)); |
58 | Poll::Ready(Ok(())) |
59 | } |
60 | } |
61 | |
62 | impl AsyncBufRead for Empty { |
63 | #[inline ] |
64 | fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> { |
65 | ready!(crate::trace::trace_leaf(cx)); |
66 | ready!(poll_proceed_and_make_progress(cx)); |
67 | Poll::Ready(Ok(&[])) |
68 | } |
69 | |
70 | #[inline ] |
71 | fn consume(self: Pin<&mut Self>, _: usize) {} |
72 | } |
73 | |
74 | impl fmt::Debug for Empty { |
75 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
76 | f.pad("Empty { .. }" ) |
77 | } |
78 | } |
79 | |
80 | cfg_coop! { |
81 | fn poll_proceed_and_make_progress(cx: &mut Context<'_>) -> Poll<()> { |
82 | let coop = ready!(crate::runtime::coop::poll_proceed(cx)); |
83 | coop.made_progress(); |
84 | Poll::Ready(()) |
85 | } |
86 | } |
87 | |
88 | cfg_not_coop! { |
89 | fn poll_proceed_and_make_progress(_: &mut Context<'_>) -> Poll<()> { |
90 | Poll::Ready(()) |
91 | } |
92 | } |
93 | |
94 | #[cfg (test)] |
95 | mod tests { |
96 | use super::*; |
97 | |
98 | #[test] |
99 | fn assert_unpin() { |
100 | crate::is_unpin::<Empty>(); |
101 | } |
102 | } |
103 | |