4

I have a custom socket that implements AsyncWrite and AsyncRead. I'd like to store a dyn to this socket, but I'd like to use both AsyncWrite/Read, like this:

#[derive(Clone)]
pub struct AsyncTransporter {
    stream: Arc<dyn AsyncRead + AsyncWrite>,
}  

but this is not supported.

60 |     stream: Arc<dyn AsyncRead + AsyncWrite>,
   |                     ---------   ^^^^^^^^^^ additional non-auto trait
   |                     |
   |                     first non-auto trait
   |
   = help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: tokio::io::AsyncRead + tokio::io::AsyncWrite {}`

If I do trait NewTrait: tokio::io::AsyncRead + tokio::io::AsyncWrite {}, how will the methods of both traits be implemented?

Guerlando OCs
  • 1,886
  • 9
  • 61
  • 150
  • [Is there any way to create a type alias for multiple traits?](https://stackoverflow.com/questions/26070559/is-there-any-way-to-create-a-type-alias-for-multiple-traits) – kmdreko Jun 16 '21 at 06:22

1 Answers1

6

If I do trait NewTrait: tokio::io::AsyncRead + tokio::io::AsyncWrite {}, how will the methods of both traits be implemented?

trait NewTrait: tokio::io::AsyncRead + tokio::io::AsyncWrite {} requires implementors of NewTrait to first implement AsyncRead and AsyncWrite, so if you have a type that implements NewTrait, you can count on AsyncRead and AsyncWrite's methods just being there. Thus it's not so much a question of "how will the methods of both traits be implemented", but of "how will NewTrait be implemented for an arbitrary type that implements AsyncRead and AsyncWrite and knows nothing of NewTrait?"

The response is, by providing a blanket implementation of NewTrait for all types that implement the two:

impl<T> NewTrait for T
where
    T: AsyncRead + AsyncWrite
{
}

With that implementation, any type (even one defined in another crate) that implements both AsyncRead and AsyncWrite also implements NewTrait.

user4815162342
  • 141,790
  • 18
  • 296
  • 355
  • I tried this and called the new trait `AsyncRW` but I get `self.stream.poll_read(cx, buf) | ^^^^^^^^^ method not found in `Arc<(dyn AsyncRW + 'static)>`` – Guerlando OCs Jun 16 '21 at 18:26
  • @GuerlandoOCs Maybe the problem is that `poll_read()` requires `&mut self`, so it won't work through an Arc? – user4815162342 Jun 16 '21 at 21:23
  • Indeed. What should I do then? `Arc>` is not good as it would block inside `poll_read` – Guerlando OCs Jun 18 '21 at 02:55
  • @GuerlandoOCs There are async mutexes that are acquired via an async fn, e.g. [this one](https://tokio-rs.github.io/tokio/doc/tokio/sync/struct.Mutex.html). That seems outside the scope of this question, though. – user4815162342 Jun 18 '21 at 09:23