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