I have a struct MyAsyncStream and tokio::io::AsyncWrite implementation for it:
impl<S: AsyncRead + AsyncWrite + Unpin> AsyncWrite for MyAsyncStream<S> {
fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>> {
....
}
I also have MyAsyncStreamWrapper:
struct MyAsyncStreamWrapper{inner: MyAsyncStream}
Now I want to implement AnotherTrait trait for MyAsyncStreamWrapper, with the following method:
impl AnotherTrait for MyAsyncStreamWrapper {
fn poll_send_to<B>(self: Pin<&Self>, cx: &mut Context<'_>, buf: &[u8], addr: B,) -> Poll<Result<usize, Self::Error>> {
Pin::new(&mut self.inner).poll_write(cx, buf)
}
....
}
In this method implementation, I want to call poll_write on the inner. But, unfortunately they are different on self mutability: Pin<&mut Self> vs Pin<&Self>. As expected it does not compile.
Is there an idiomatic "workaround" for such case? My idea is to wrap inner into Mutex so I could have mutable MyAsyncStream in the non-mutable context:
MyAsyncStreamWrapper{inner: Mutex<RefCell<MyAsyncStream>>}
...
fn poll_send_to<B>(mut self: Pin<&Self>, cx: &mut Context<'_>, buf: &[u8], addr: B,) -> Poll<Result<usize, Self::Error>> {
let rc = self.stream.lock().unwrap();
let ref mut inner = rc.borrow();
let pin = Pin::new(inner);
pin.poll_write(cx, buf);
}
...
But, unfortunately, it also does not compile, with the following error:
pin.poll_write(cx, buf);
^^^^^^^^^^ method not found in `std::pin::Pin<&mut std::cell::RefMut<'_, MyAsyncStream>>`
What is the right way to go?