I am trying to use a crate that has a very.... interesting ownership model.
Really, all I actually want to make work is just:
struct RTTClient<'a> {
decoder: Box<dyn StreamDecoder + Send + Sync 'a>
}
impl<'a> RTTClient<'a> {
pub fn new() -> Self {
let table = dumb_crate::create_the_table();
let decoder = table.new_stream_decoder();
Self {
decoder
}
}
}
The problem is, table.new_stream_decoder returns a struct with a permanent reference to table:
See here
pub fn new_stream_decoder(&self) -> Box<dyn StreamDecoder + Send + Sync + '_> {
match self.encoding {
Encoding::Raw => Box::new(stream::Raw::new(self)),
Encoding::Rzcobs => Box::new(stream::Rzcobs::new(self)),
}
}
And, for reference
impl<'a> Raw<'a> {
pub fn new(table: &'a Table) -> Self {
Self {
table,
data: Vec::new(),
}
}
}
The result is that table gets dropped when RTTClient::new returns.
So, my immediate thought was: Let's have RTTClient take ownership of table, that way it's not dropped:
struct RTTClient<'a> {
decoder: Box<dyn StreamDecoder + Send + Sync 'a>,
table: Table
}
impl<'a> RTTClient<'a> {
pub fn new() -> Self {
let table = dumb_crate::create_the_table();
let decoder = table.new_stream_decoder();
Self {
table,
decoder
}
}
}
That doesn't work, either, though. Because decoder has borrowed table, I am not allowed to move it into RTTClient.
So, great, the way decoder is constructed has prevented me simultaneously from allowing table to drop and from preventing table from dropping.
I'm stumped -- What on earth is one supposed to do in this situation? I feel like there MUST be a good solution to this, but I've been pondering this a couple hours now and still am coming up short.
The only usage example I have here is another crate (probe.rs) and IIRC they just straight up do an unsafe transmute to bypass this issue, which I don't wanna do.