futures_util_io_peek/
lib.rs1#![forbid(unsafe_code)]
2
3mod lib_io;
5pub use lib_io::AsyncPeek;
6
7pub 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
18mod 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
52mod 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}