I want to pass a closure go be executed on the poll_read and poll_write of a struct:
use core::task::{Context, Poll};
use std::pin::Pin;
use hyper::client::connect::{Connection, Connected};
use tokio::io::{AsyncRead, AsyncWrite};
use std::sync::Arc;
pub type OnPollRead = Arc<dyn Fn(&mut Context<'_>, &mut tokio::io::ReadBuf<'_>) -> Poll<std::io::Result<()>> + Send + Sync>;
pub type OnPollWrite = Arc<dyn Fn(&mut Context<'_>, &[u8]) -> Poll<core::result::Result<usize, std::io::Error>> + Send + Sync>;
pub struct CustomResponse {
on_poll_read: Option<OnPollRead>,
on_poll_write: Option<OnPollWrite>,
}
impl AsyncRead for CustomResponse {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut tokio::io::ReadBuf<'_>
) -> Poll<std::io::Result<()>> {
(self.on_poll_read)(cx.waker().clone(), buf)
}
}
impl AsyncWrite for CustomResponse {
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8]
) -> Poll<Result<usize, std::io::Error>> {
(self.on_poll_write)(cx.waker().clone(), buf)
}
fn poll_flush(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>
) -> Poll<Result<(), std::io::Error>> {
Poll::Ready(Ok(()))
}
fn poll_shutdown(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>
) -> Poll<Result<(), std::io::Error>>
{
Poll::Ready(Ok(()))
}
}
fn main() {
let on_poll_read = Arc::new(|&mut Context, &mut tokio::io::ReadBuf| -> Poll<std::io::Result<()>> {
Poll::Ready(Ok(()))
});
let on_poll_write = Arc::new(|&mut Context, &[u8]| -> Poll<core::result::Result<usize, std::io::Error>>{
Poll::Ready(Ok(0))
});
}
I get these errors:
error[E0532]: expected unit struct, unit variant or constant, found struct `tokio::io::ReadBuf`
--> src/main.rs:47:53
|
47 | let on_poll_read = Arc::new(|&mut Context, &mut tokio::io::ReadBuf| -> Poll<std::io::Result<()>> {
| ^^^^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `tokio::io::ReadBuf { buf, filled, initialized }`
|
::: /root/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.2.0/src/io/read_buf.rs:27:1
|
27 | pub struct ReadBuf<'a> {
| ---------------------- `tokio::io::ReadBuf` defined here
error[E0277]: the size for values of type `dyn for<'r, 's, 't0> Fn(&'r mut Context<'s>, &'t0 [u8]) -> Poll<std::result::Result<usize, std::io::Error>> + Send + Sync` cannot be known at compilation time
--> src/main.rs:50:25
|
50 | let on_poll_write = Arc::new(|&mut Context, &[u8]| -> Poll<core::result::Result<usize, std::io::Error>>{
| ^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn for<'r, 's, 't0> Fn(&'r mut Context<'s>, &'t0 [u8]) -> Poll<std::result::Result<usize, std::io::Error>> + Send + Sync`
= note: required by `Arc::<T>::new`
error[E0618]: expected function, found enum variant `(self.on_poll_read)`
--> src/custom_transporter.rs:54:9
|
54 | (self.on_poll_read)(cx.waker().clone(), buf)
| ^^^^^^^^^^^^^^^^^^^-------------------------
| |
| call expression requires function
|
help: `(self.on_poll_read)` is a unit variant, you need to write it without the parenthesis
|
54 | (self.on_poll_read)
|
I tried help: (self.on_poll_read) is a unit variant, you need to write it without the parenthesis, but without the parenthesis, I get
error[E0599]: no method named `on_poll_write` found for struct `Pin<&mut CustomResponse>` in the current scope
which is even more strange.
Also, for expected unit struct, unit variant or constant, found structtokio::io::ReadBuf``, I have no idea of what's happening
Here's a playground with the errors: Rust Playground