I am trying to send a message containing Cow<[u8]> over a channel. However, the lifetime rules do not allow me to pass it over.
use std::borrow::Cow;
use std::sync::mpsc;
#[derive(Debug, Default, PartialEq, Clone)]
pub struct PlayerAction<'a> {
pub data: Cow<'a, [u8]>,
}
#[derive(Debug, Clone)]
pub enum NetworkMessage<'a> {
PlayerActionMessage(PlayerAction<'a>),
}
pub struct ConnectionsManager<'a> {
channel: mpsc::Sender<NetworkMessage<'a>>,
}
pub struct MessageHandler<'a> {
pub connection_manager: ConnectionsManager<'a>,
}
fn read_message<'a>(bytes: &'a Vec<u8>) -> NetworkMessage {
NetworkMessage::PlayerActionMessage(PlayerAction {
data: Cow::Borrowed(&bytes),
})
}
impl<'a> MessageHandler<'a> {
fn on_message(&mut self, msg: Vec<u8>) {
let readm = read_message(&msg);
self.connection_manager.channel.send(readm);
}
}
fn main() {}
error[E0597]: `msg` does not live long enough
--> src/main.rs:30:35
|
30 | let readm = read_message(&msg);
| ^^^ borrowed value does not live long enough
31 | self.connection_manager.channel.send(readm);
32 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 28:1...
--> src/main.rs:28:1
|
28 | impl<'a> MessageHandler<'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
MessageHandler outlives Vec<u8>, but I have no idea how to pass it any other way.
Is there any way to pass Vec<u8> so that it can live longer than the on_message function?
Here's a one-line change you can make to make this code correct:
Instead of taking a
Vec<u8>by value, take a reference to a slice that is already guaranteed to live at least as long as'a. This makes it the caller's responsibility to ensure that whatever you pass toon_messagewill live long enough to be sent over the channel.But maybe you can't do that. Either the caller will have the same problem, and you can't push it up any farther, or the
Vec<u8>is a required part ofon_message's signature. If that's the case, you will have to changeread_message. Here's one possibility:Moving
msgintoread_messageleaves the compiler free to pick any lifetime it wants for'b. Inon_messageit can just pick'ato make the code compile. The disadvantage of this approach is that you may have to.clone()theVecif you need to use it again after sending it down the channel.