I have a function where the user can pass in an object writer that implements AsyncWrite as an argument.
I save that writer and when needed, I start an asynchronous task to call the write() interface of that writer to send the data out.
For my needs, I simplified a test program in which I start a TCP server. i simulate the above required writer object with a TCP Stream client.
The TCP server receives the corresponding data and prints it out. Now it is the under_test() function that does not compile. It prompts the error.
use std::sync::Arc;
use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt};
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::Mutex;
#[tokio::test]
async fn test_spawn_move_writable() {
async fn under_test<T: AsyncWrite>(writer: Arc<Mutex<T>>, data: &[u8]) {
tokio::spawn(async move {
let writer = writer.lock().await;
writer.write(data);
// `T` cannot be unpinned
// consider using `Box::pin`
})
.await
.unwrap();
}
let addr = "127.0.0.1:3000";
let tcps = TcpListener::bind(addr).await.unwrap();
tokio::spawn(async move {
loop {
let (mut client, caddr) = tcps.accept().await.unwrap();
tokio::spawn(async move {
let mut buf = vec![0; 16];
loop {
let size = client.read(&mut buf).await.unwrap();
println!(
"{:?}> {}",
caddr,
std::str::from_utf8(&buf[0..size]).unwrap()
);
}
});
}
});
let tcps = TcpStream::connect(addr).await.unwrap();
let tcps = Arc::new(Mutex::new(tcps));
for data in [b"hello", b"world", b"rustl", b"tokio"] {
under_test(tcps.clone(), &data[..]).await;
}
}