I want to be able to pass my struct as AsRef<[u8]>
but that does not work and I don't know what the error means and how to fix it.
#[derive(Serialize, Deserialize, ToSchema, Clone, Message, Debug)]
#[rtype(result = "()")]
pub struct Data {
id: i32,
images: Vec<i32>,
queries: Vec<i32>,
iot_queries: Vec<i32>,
time: String,
location: String
}
impl AsRef<[u8]> for Data {
fn as_ref(&self) -> &[u8] {
let data_vec = bincode::serialize(self).unwrap();
data_vec.as_slice()
}
}
error[E0515]: cannot return value referencing local variable `data_vec`
--> src/service/data_collection_service.rs:38:9
|
38 | data_vec.as_slice()
| --------^^^^^^^^^^^
| |
| returns a value referencing data owned by the current function
| `data_vec` is borrowed here
For more information about this error, try `rustc --explain E0515`.
You can't construct a local variable and return a reference to it: the local variable goes out of scope at the end of the method. And you can't return a &[u8]
to yourself that covers your owned data either: even ignoring potential padding issues and the like, your data is not contiguous; it's a mix of inline data and data held in separate heap allocations.
You could box up the serialized bytes and leak them, but leaking is almost never what people want either.
So what you want isn't available in any useful form. The signature of AsRef<T>
basically means that the T
has to be present within self
somewhere. The [u8]
you wish you could return is not present, so this is the wrong API for that desire.
3 Likes
Congrats, Rust just saved you from a use-after-free error.
For the reasons outlined by the previous answer, what you want is impossible. What you can do is
impl Data {
fn to_bytes(&self) -> Vec<u8> {
bincode::serialize(self).unwrap()
}
}
and then make the caller hold on to the returned buffer for as long as possible.
But that's not terribly useful, because it doesn't do anything that bincode::serialize()
doesn't do, and it hides the potential error and makes your program panic upon serialization error.
1 Like