Implement Into for Trait

I am using message passing to pass requests among some tokio environments.

For the response of a request I use a tokio::sync::oneshot::Sender<String>. Unfortunately the send method requires self and the compiler complains the size is not known so I can not use self.

pub trait Request: tokio::io::AsyncRead + Send + Unpin {
    fn size(&self) -> usize;
    fn into_response_channel(self) -> tokio::sync::oneshot::Sender<String>;
    fn send(self, str: String) { // the size for values of type `Self` cannot be known at compilation time
        self.into_response_channel().send(str);
    }
}

If I try to request that the Trait implements Into oneshot::Sender, then I can no longer use it as an object

pub trait Request: tokio::io::AsyncRead + Send + Unpin + Into<tokio::sync::oneshot::Sender<String>> {
    fn size(&self) -> usize;
}
// error[E0038]: the trait `runtime::worker::worker::Request` cannot be made into an object

The only workaround I see is wrapping the oneshot::Sender in an Option.

Is there any better idea?

Note that I am not using generics, because the Request objects may vary for a single Worker instance (the one that processes the requests).

Edit: I misread your question, but the following might be useful information anyway.

You can have a variants of send and into_response_channel that take self: Box<Self> instead of a plain self:

pub trait Request: tokio::io::AsyncRead + Send + Unpin {
    fn size(&self) -> usize;
    fn into_response_channel(self) -> tokio::sync::oneshot::Sender<String> where Self: Sized;

    fn into_response_channel_boxed(self: Box<Self>) -> tokio::sync::oneshot::Sender<String>;

    fn send(self, str: String) where Self: Sized {
        self.into_response_channel().send(str);
    }

    fn send_boxed(self: Box<Self>, str:String) {
        self.into_response_channel_boxed().send(str);
    }
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=15e3d27f32a48ca64f34759b660d7c9c

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.