1 //! Asynchronous I/O
2 //!
3 //! This crate contains the `AsyncRead`, `AsyncWrite`, `AsyncSeek`, and
4 //! `AsyncBufRead` traits, the asynchronous analogs to
5 //! `std::io::{Read, Write, Seek, BufRead}`. The primary difference is
6 //! that these traits integrate with the asynchronous task system.
7 //!
8 //! All items of this library are only available when the `std` feature of this
9 //! library is activated, and it is activated by default.
10 
11 #![cfg_attr(all(feature = "read-initializer", feature = "std"), feature(read_initializer))]
12 
13 #![cfg_attr(not(feature = "std"), no_std)]
14 
15 #![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
16 // It cannot be included in the published code because this lints have false positives in the minimum required version.
17 #![cfg_attr(test, warn(single_use_lifetimes))]
18 #![warn(clippy::all)]
19 #![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))]
20 
21 #![cfg_attr(docsrs, feature(doc_cfg))]
22 
23 #[cfg(all(feature = "read-initializer", not(feature = "unstable")))]
24 compile_error!("The `read-initializer` feature requires the `unstable` feature as an explicit opt-in to unstable features");
25 
26 #[cfg(feature = "std")]
27 mod if_std {
28     use std::io;
29     use std::ops::DerefMut;
30     use std::pin::Pin;
31     use std::task::{Context, Poll};
32 
33     // Re-export some types from `std::io` so that users don't have to deal
34     // with conflicts when `use`ing `futures::io` and `std::io`.
35     #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
36     #[doc(no_inline)]
37     pub use io::{Error, ErrorKind, Result, IoSlice, IoSliceMut, SeekFrom};
38     #[cfg(feature = "read-initializer")]
39     #[cfg_attr(docsrs, doc(cfg(feature = "read-initializer")))]
40     #[doc(no_inline)]
41     #[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
42     pub use io::Initializer;
43 
44     /// Read bytes asynchronously.
45     ///
46     /// This trait is analogous to the `std::io::Read` trait, but integrates
47     /// with the asynchronous task system. In particular, the `poll_read`
48     /// method, unlike `Read::read`, will automatically queue the current task
49     /// for wakeup and return if data is not yet available, rather than blocking
50     /// the calling thread.
51     pub trait AsyncRead {
52         /// Determines if this `AsyncRead`er can work with buffers of
53         /// uninitialized memory.
54         ///
55         /// The default implementation returns an initializer which will zero
56         /// buffers.
57         ///
58         /// This method is only available when the `read-initializer` feature of this
59         /// library is activated.
60         ///
61         /// # Safety
62         ///
63         /// This method is `unsafe` because an `AsyncRead`er could otherwise
64         /// return a non-zeroing `Initializer` from another `AsyncRead` type
65         /// without an `unsafe` block.
66         #[cfg(feature = "read-initializer")]
67         #[cfg_attr(docsrs, doc(cfg(feature = "read-initializer")))]
68         #[inline]
initializer(&self) -> Initializer69         unsafe fn initializer(&self) -> Initializer {
70             Initializer::zeroing()
71         }
72 
73         /// Attempt to read from the `AsyncRead` into `buf`.
74         ///
75         /// On success, returns `Poll::Ready(Ok(num_bytes_read))`.
76         ///
77         /// If no data is available for reading, the method returns
78         /// `Poll::Pending` and arranges for the current task (via
79         /// `cx.waker().wake_by_ref()`) to receive a notification when the object becomes
80         /// readable or is closed.
81         ///
82         /// # Implementation
83         ///
84         /// This function may not return errors of kind `WouldBlock` or
85         /// `Interrupted`.  Implementations must convert `WouldBlock` into
86         /// `Poll::Pending` and either internally retry or convert
87         /// `Interrupted` into another error kind.
poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<Result<usize>>88         fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
89             -> Poll<Result<usize>>;
90 
91         /// Attempt to read from the `AsyncRead` into `bufs` using vectored
92         /// IO operations.
93         ///
94         /// This method is similar to `poll_read`, but allows data to be read
95         /// into multiple buffers using a single operation.
96         ///
97         /// On success, returns `Poll::Ready(Ok(num_bytes_read))`.
98         ///
99         /// If no data is available for reading, the method returns
100         /// `Poll::Pending` and arranges for the current task (via
101         /// `cx.waker().wake_by_ref()`) to receive a notification when the object becomes
102         /// readable or is closed.
103         /// By default, this method delegates to using `poll_read` on the first
104         /// nonempty buffer in `bufs`, or an empty one if none exists. Objects which
105         /// support vectored IO should override this method.
106         ///
107         /// # Implementation
108         ///
109         /// This function may not return errors of kind `WouldBlock` or
110         /// `Interrupted`.  Implementations must convert `WouldBlock` into
111         /// `Poll::Pending` and either internally retry or convert
112         /// `Interrupted` into another error kind.
poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>]) -> Poll<Result<usize>>113         fn poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
114             -> Poll<Result<usize>>
115         {
116             for b in bufs {
117                 if !b.is_empty() {
118                     return self.poll_read(cx, b);
119                 }
120             }
121 
122             self.poll_read(cx, &mut [])
123         }
124     }
125 
126     /// Write bytes asynchronously.
127     ///
128     /// This trait is analogous to the `std::io::Write` trait, but integrates
129     /// with the asynchronous task system. In particular, the `poll_write`
130     /// method, unlike `Write::write`, will automatically queue the current task
131     /// for wakeup and return if the writer cannot take more data, rather than blocking
132     /// the calling thread.
133     pub trait AsyncWrite {
134         /// Attempt to write bytes from `buf` into the object.
135         ///
136         /// On success, returns `Poll::Ready(Ok(num_bytes_written))`.
137         ///
138         /// If the object is not ready for writing, the method returns
139         /// `Poll::Pending` and arranges for the current task (via
140         /// `cx.waker().wake_by_ref()`) to receive a notification when the object becomes
141         /// writable or is closed.
142         ///
143         /// # Implementation
144         ///
145         /// This function may not return errors of kind `WouldBlock` or
146         /// `Interrupted`.  Implementations must convert `WouldBlock` into
147         /// `Poll::Pending` and either internally retry or convert
148         /// `Interrupted` into another error kind.
149         ///
150         /// `poll_write` must try to make progress by flushing the underlying object if
151         /// that is the only way the underlying object can become writable again.
poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>>152         fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8])
153             -> Poll<Result<usize>>;
154 
155         /// Attempt to write bytes from `bufs` into the object using vectored
156         /// IO operations.
157         ///
158         /// This method is similar to `poll_write`, but allows data from multiple buffers to be written
159         /// using a single operation.
160         ///
161         /// On success, returns `Poll::Ready(Ok(num_bytes_written))`.
162         ///
163         /// If the object is not ready for writing, the method returns
164         /// `Poll::Pending` and arranges for the current task (via
165         /// `cx.waker().wake_by_ref()`) to receive a notification when the object becomes
166         /// writable or is closed.
167         ///
168         /// By default, this method delegates to using `poll_write` on the first
169         /// nonempty buffer in `bufs`, or an empty one if none exists. Objects which
170         /// support vectored IO should override this method.
171         ///
172         /// # Implementation
173         ///
174         /// This function may not return errors of kind `WouldBlock` or
175         /// `Interrupted`.  Implementations must convert `WouldBlock` into
176         /// `Poll::Pending` and either internally retry or convert
177         /// `Interrupted` into another error kind.
poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>]) -> Poll<Result<usize>>178         fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>])
179             -> Poll<Result<usize>>
180         {
181             for b in bufs {
182                 if !b.is_empty() {
183                     return self.poll_write(cx, b);
184                 }
185             }
186 
187             self.poll_write(cx, &[])
188         }
189 
190         /// Attempt to flush the object, ensuring that any buffered data reach
191         /// their destination.
192         ///
193         /// On success, returns `Poll::Ready(Ok(()))`.
194         ///
195         /// If flushing cannot immediately complete, this method returns
196         /// `Poll::Pending` and arranges for the current task (via
197         /// `cx.waker().wake_by_ref()`) to receive a notification when the object can make
198         /// progress towards flushing.
199         ///
200         /// # Implementation
201         ///
202         /// This function may not return errors of kind `WouldBlock` or
203         /// `Interrupted`.  Implementations must convert `WouldBlock` into
204         /// `Poll::Pending` and either internally retry or convert
205         /// `Interrupted` into another error kind.
206         ///
207         /// It only makes sense to do anything here if you actually buffer data.
poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>208         fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>;
209 
210         /// Attempt to close the object.
211         ///
212         /// On success, returns `Poll::Ready(Ok(()))`.
213         ///
214         /// If closing cannot immediately complete, this function returns
215         /// `Poll::Pending` and arranges for the current task (via
216         /// `cx.waker().wake_by_ref()`) to receive a notification when the object can make
217         /// progress towards closing.
218         ///
219         /// # Implementation
220         ///
221         /// This function may not return errors of kind `WouldBlock` or
222         /// `Interrupted`.  Implementations must convert `WouldBlock` into
223         /// `Poll::Pending` and either internally retry or convert
224         /// `Interrupted` into another error kind.
poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>225         fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>;
226     }
227 
228     /// Seek bytes asynchronously.
229     ///
230     /// This trait is analogous to the `std::io::Seek` trait, but integrates
231     /// with the asynchronous task system. In particular, the `poll_seek`
232     /// method, unlike `Seek::seek`, will automatically queue the current task
233     /// for wakeup and return if data is not yet available, rather than blocking
234     /// the calling thread.
235     pub trait AsyncSeek {
236         /// Attempt to seek to an offset, in bytes, in a stream.
237         ///
238         /// A seek beyond the end of a stream is allowed, but behavior is defined
239         /// by the implementation.
240         ///
241         /// If the seek operation completed successfully,
242         /// this method returns the new position from the start of the stream.
243         /// That position can be used later with [`SeekFrom::Start`].
244         ///
245         /// # Errors
246         ///
247         /// Seeking to a negative offset is considered an error.
248         ///
249         /// # Implementation
250         ///
251         /// This function may not return errors of kind `WouldBlock` or
252         /// `Interrupted`.  Implementations must convert `WouldBlock` into
253         /// `Poll::Pending` and either internally retry or convert
254         /// `Interrupted` into another error kind.
poll_seek(self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom) -> Poll<Result<u64>>255         fn poll_seek(self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom)
256             -> Poll<Result<u64>>;
257     }
258 
259     /// Read bytes asynchronously.
260     ///
261     /// This trait is analogous to the `std::io::BufRead` trait, but integrates
262     /// with the asynchronous task system. In particular, the `poll_fill_buf`
263     /// method, unlike `BufRead::fill_buf`, will automatically queue the current task
264     /// for wakeup and return if data is not yet available, rather than blocking
265     /// the calling thread.
266     pub trait AsyncBufRead: AsyncRead {
267         /// Attempt to return the contents of the internal buffer, filling it with more data
268         /// from the inner reader if it is empty.
269         ///
270         /// On success, returns `Poll::Ready(Ok(buf))`.
271         ///
272         /// If no data is available for reading, the method returns
273         /// `Poll::Pending` and arranges for the current task (via
274         /// `cx.waker().wake_by_ref()`) to receive a notification when the object becomes
275         /// readable or is closed.
276         ///
277         /// This function is a lower-level call. It needs to be paired with the
278         /// [`consume`] method to function properly. When calling this
279         /// method, none of the contents will be "read" in the sense that later
280         /// calling [`poll_read`] may return the same contents. As such, [`consume`] must
281         /// be called with the number of bytes that are consumed from this buffer to
282         /// ensure that the bytes are never returned twice.
283         ///
284         /// [`poll_read`]: AsyncRead::poll_read
285         /// [`consume`]: AsyncBufRead::consume
286         ///
287         /// An empty buffer returned indicates that the stream has reached EOF.
288         ///
289         /// # Implementation
290         ///
291         /// This function may not return errors of kind `WouldBlock` or
292         /// `Interrupted`.  Implementations must convert `WouldBlock` into
293         /// `Poll::Pending` and either internally retry or convert
294         /// `Interrupted` into another error kind.
poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>>295         fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>)
296             -> Poll<Result<&[u8]>>;
297 
298         /// Tells this buffer that `amt` bytes have been consumed from the buffer,
299         /// so they should no longer be returned in calls to [`poll_read`].
300         ///
301         /// This function is a lower-level call. It needs to be paired with the
302         /// [`poll_fill_buf`] method to function properly. This function does
303         /// not perform any I/O, it simply informs this object that some amount of
304         /// its buffer, returned from [`poll_fill_buf`], has been consumed and should
305         /// no longer be returned. As such, this function may do odd things if
306         /// [`poll_fill_buf`] isn't called before calling it.
307         ///
308         /// The `amt` must be `<=` the number of bytes in the buffer returned by
309         /// [`poll_fill_buf`].
310         ///
311         /// [`poll_read`]: AsyncRead::poll_read
312         /// [`poll_fill_buf`]: AsyncBufRead::poll_fill_buf
consume(self: Pin<&mut Self>, amt: usize)313         fn consume(self: Pin<&mut Self>, amt: usize);
314     }
315 
316     macro_rules! deref_async_read {
317         () => {
318             #[cfg(feature = "read-initializer")]
319             unsafe fn initializer(&self) -> Initializer {
320                 (**self).initializer()
321             }
322 
323             fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
324                 -> Poll<Result<usize>>
325             {
326                 Pin::new(&mut **self).poll_read(cx, buf)
327             }
328 
329             fn poll_read_vectored(mut self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
330                 -> Poll<Result<usize>>
331             {
332                 Pin::new(&mut **self).poll_read_vectored(cx, bufs)
333             }
334         }
335     }
336 
337     impl<T: ?Sized + AsyncRead + Unpin> AsyncRead for Box<T> {
338         deref_async_read!();
339     }
340 
341     impl<T: ?Sized + AsyncRead + Unpin> AsyncRead for &mut T {
342         deref_async_read!();
343     }
344 
345     impl<P> AsyncRead for Pin<P>
346     where
347         P: DerefMut + Unpin,
348         P::Target: AsyncRead,
349     {
350         #[cfg(feature = "read-initializer")]
initializer(&self) -> Initializer351         unsafe fn initializer(&self) -> Initializer {
352             (**self).initializer()
353         }
354 
poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<Result<usize>>355         fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
356             -> Poll<Result<usize>>
357         {
358             self.get_mut().as_mut().poll_read(cx, buf)
359         }
360 
poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>]) -> Poll<Result<usize>>361         fn poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
362             -> Poll<Result<usize>>
363         {
364             self.get_mut().as_mut().poll_read_vectored(cx, bufs)
365         }
366     }
367 
368     macro_rules! delegate_async_read_to_stdio {
369         () => {
370             #[cfg(feature = "read-initializer")]
371             unsafe fn initializer(&self) -> Initializer {
372                 io::Read::initializer(self)
373             }
374 
375             fn poll_read(mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &mut [u8])
376                 -> Poll<Result<usize>>
377             {
378                 Poll::Ready(io::Read::read(&mut *self, buf))
379             }
380 
381             fn poll_read_vectored(mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
382                 -> Poll<Result<usize>>
383             {
384                 Poll::Ready(io::Read::read_vectored(&mut *self, bufs))
385             }
386         }
387     }
388 
389     impl AsyncRead for &[u8] {
390         delegate_async_read_to_stdio!();
391     }
392 
393     macro_rules! deref_async_write {
394         () => {
395             fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8])
396                 -> Poll<Result<usize>>
397             {
398                 Pin::new(&mut **self).poll_write(cx, buf)
399             }
400 
401             fn poll_write_vectored(mut self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>])
402                 -> Poll<Result<usize>>
403             {
404                 Pin::new(&mut **self).poll_write_vectored(cx, bufs)
405             }
406 
407             fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
408                 Pin::new(&mut **self).poll_flush(cx)
409             }
410 
411             fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
412                 Pin::new(&mut **self).poll_close(cx)
413             }
414         }
415     }
416 
417     impl<T: ?Sized + AsyncWrite + Unpin> AsyncWrite for Box<T> {
418         deref_async_write!();
419     }
420 
421     impl<T: ?Sized + AsyncWrite + Unpin> AsyncWrite for &mut T {
422         deref_async_write!();
423     }
424 
425     impl<P> AsyncWrite for Pin<P>
426     where
427         P: DerefMut + Unpin,
428         P::Target: AsyncWrite,
429     {
poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>>430         fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8])
431             -> Poll<Result<usize>>
432         {
433             self.get_mut().as_mut().poll_write(cx, buf)
434         }
435 
poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>]) -> Poll<Result<usize>>436         fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>])
437             -> Poll<Result<usize>>
438         {
439             self.get_mut().as_mut().poll_write_vectored(cx, bufs)
440         }
441 
poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>442         fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
443             self.get_mut().as_mut().poll_flush(cx)
444         }
445 
poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>>446         fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
447             self.get_mut().as_mut().poll_close(cx)
448         }
449     }
450 
451     macro_rules! delegate_async_write_to_stdio {
452         () => {
453             fn poll_write(mut self: Pin<&mut Self>, _: &mut Context<'_>, buf: &[u8])
454                 -> Poll<Result<usize>>
455             {
456                 Poll::Ready(io::Write::write(&mut *self, buf))
457             }
458 
459             fn poll_write_vectored(mut self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>])
460                 -> Poll<Result<usize>>
461             {
462                 Poll::Ready(io::Write::write_vectored(&mut *self, bufs))
463             }
464 
465             fn poll_flush(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<()>> {
466                 Poll::Ready(io::Write::flush(&mut *self))
467             }
468 
469             fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
470                 self.poll_flush(cx)
471             }
472         }
473     }
474 
475     impl AsyncWrite for Vec<u8> {
476         delegate_async_write_to_stdio!();
477     }
478 
479     macro_rules! deref_async_seek {
480         () => {
481             fn poll_seek(mut self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom)
482                 -> Poll<Result<u64>>
483             {
484                 Pin::new(&mut **self).poll_seek(cx, pos)
485             }
486         }
487     }
488 
489     impl<T: ?Sized + AsyncSeek + Unpin> AsyncSeek for Box<T> {
490         deref_async_seek!();
491     }
492 
493     impl<T: ?Sized + AsyncSeek + Unpin> AsyncSeek for &mut T {
494         deref_async_seek!();
495     }
496 
497     impl<P> AsyncSeek for Pin<P>
498     where
499         P: DerefMut + Unpin,
500         P::Target: AsyncSeek,
501     {
poll_seek(self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom) -> Poll<Result<u64>>502         fn poll_seek(self: Pin<&mut Self>, cx: &mut Context<'_>, pos: SeekFrom)
503             -> Poll<Result<u64>>
504         {
505             self.get_mut().as_mut().poll_seek(cx, pos)
506         }
507     }
508 
509     macro_rules! deref_async_buf_read {
510         () => {
511             fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>)
512                 -> Poll<Result<&[u8]>>
513             {
514                 Pin::new(&mut **self.get_mut()).poll_fill_buf(cx)
515             }
516 
517             fn consume(mut self: Pin<&mut Self>, amt: usize) {
518                 Pin::new(&mut **self).consume(amt)
519             }
520         }
521     }
522 
523     impl<T: ?Sized + AsyncBufRead + Unpin> AsyncBufRead for Box<T> {
524         deref_async_buf_read!();
525     }
526 
527     impl<T: ?Sized + AsyncBufRead + Unpin> AsyncBufRead for &mut T {
528         deref_async_buf_read!();
529     }
530 
531     impl<P> AsyncBufRead for Pin<P>
532     where
533         P: DerefMut + Unpin,
534         P::Target: AsyncBufRead,
535     {
poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>>536         fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>)
537             -> Poll<Result<&[u8]>>
538         {
539             self.get_mut().as_mut().poll_fill_buf(cx)
540         }
541 
consume(self: Pin<&mut Self>, amt: usize)542         fn consume(self: Pin<&mut Self>, amt: usize) {
543             self.get_mut().as_mut().consume(amt)
544         }
545     }
546 
547     macro_rules! delegate_async_buf_read_to_stdio {
548         () => {
549             fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>)
550                 -> Poll<Result<&[u8]>>
551             {
552                 Poll::Ready(io::BufRead::fill_buf(self.get_mut()))
553             }
554 
555             fn consume(self: Pin<&mut Self>, amt: usize) {
556                 io::BufRead::consume(self.get_mut(), amt)
557             }
558         }
559     }
560 
561     impl AsyncBufRead for &[u8] {
562         delegate_async_buf_read_to_stdio!();
563     }
564 }
565 
566 #[cfg(feature = "std")]
567 pub use self::if_std::*;
568