• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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]
poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, _: &mut ReadBuf<'_>, ) -> Poll<io::Result<()>>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]
poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>>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]
consume(self: Pin<&mut Self>, _: usize)71     fn consume(self: Pin<&mut Self>, _: usize) {}
72 }
73 
74 impl fmt::Debug for Empty {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result75     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]
assert_unpin()99     fn assert_unpin() {
100         crate::is_unpin::<Empty>();
101     }
102 }
103