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_message
will 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
msg
intoread_message
leaves the compiler free to pick any lifetime it wants for'b
. Inon_message
it can just pick'a
to make the code compile. The disadvantage of this approach is that you may have to.clone()
theVec
if you need to use it again after sending it down the channel.