1use crate::io::{AsyncBufRead, AsyncRead, ReadBuf};
2
3use std::fmt;
4use std::io;
5use std::pin::Pin;
6use std::task::{Context, Poll};
7
8cfg_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
49impl 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
62impl 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
74impl fmt::Debug for Empty {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 f.pad("Empty { .. }")
77 }
78}
79
80cfg_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
88cfg_not_coop! {
89 fn poll_proceed_and_make_progress(_: &mut Context<'_>) -> Poll<()> {
90 Poll::Ready(())
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn assert_unpin() {
100 crate::is_unpin::<Empty>();
101 }
102}
103