futures_util_io_peek/
lib.rs

1#![forbid(unsafe_code)]
2
3//
4mod lib_io;
5pub use lib_io::AsyncPeek;
6
7// ref https://github.com/rust-lang/futures-rs/blob/0.3.5/futures-util/src/io/mod.rs#L132-L382
8pub trait AsyncPeekExt: AsyncPeek {
9    fn peek_async<'a>(&'a mut self, buf: &'a mut [u8]) -> Peek<'a, Self>
10    where
11        Self: Unpin,
12    {
13        Peek::new(self, buf)
14    }
15}
16impl<R: AsyncPeek + ?Sized> AsyncPeekExt for R {}
17
18// ref https://github.com/rust-lang/futures-rs/blob/0.3.5/futures-util/src/io/read.rs
19mod peek {
20    use crate::AsyncPeek;
21
22    use core::{
23        future::Future,
24        pin::Pin,
25        task::{Context, Poll},
26    };
27    use std::io;
28
29    pub struct Peek<'a, R: ?Sized> {
30        reader: &'a mut R,
31        buf: &'a mut [u8],
32    }
33
34    impl<R: ?Sized + Unpin> Unpin for Peek<'_, R> {}
35
36    impl<'a, R: AsyncPeek + ?Sized + Unpin> Peek<'a, R> {
37        pub(super) fn new(reader: &'a mut R, buf: &'a mut [u8]) -> Self {
38            Peek { reader, buf }
39        }
40    }
41
42    impl<R: AsyncPeek + ?Sized + Unpin> Future for Peek<'_, R> {
43        type Output = io::Result<usize>;
44        fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
45            let this = &mut *self;
46            Pin::new(&mut this.reader).poll_peek(cx, this.buf)
47        }
48    }
49}
50pub use peek::*;
51
52// ref https://github.com/rust-lang/futures-rs/blob/0.3.5/futures-util/src/io/cursor.rs#L163-L185
53mod cursor {
54    use crate::AsyncPeek;
55
56    use core::{
57        pin::Pin,
58        task::{Context, Poll},
59    };
60    use std::io;
61
62    use futures_util::io::{AsyncBufRead as _, Cursor};
63
64    impl<T: AsRef<[u8]> + Unpin> AsyncPeek for Cursor<T> {
65        fn poll_peek(
66            self: Pin<&mut Self>,
67            cx: &mut Context<'_>,
68            buf: &mut [u8],
69        ) -> Poll<io::Result<usize>> {
70            self.poll_fill_buf(cx).map(|r| match r {
71                Ok(mut bytes) => {
72                    let n = bytes.len();
73                    io::copy(&mut bytes, &mut Box::new(buf))?;
74                    Ok(n)
75                }
76                Err(e) => Err(e),
77            })
78        }
79    }
80}