Reputation: 3687
I'm a rust beginner (but experienced programmer), and I'm trying to create a simple utility function to read data from a json file and am clearly missing important rust-understanding to pull it off. I've looked around but I couldn't make it work from the other rust questions. I'm trying to do something like this:
pub fn read_data_from_json<'a, T: Deserialize<'a>, P: AsRef<Path>>(path: P) -> T {
let result = std::fs::read_to_string(path).unwrap();
return serde_json::from_str(&result).unwrap();
}
The problem is that I want to provide the serde_json::from_str()
with the &str
it requires, but get a String
from reading the file. So the rust compiler says:
40 | return serde_json::from_str(&result).unwrap();
| ---------------------^^^^^^^-
| | |
| | borrowed value does not live long enough
The cause is obviously that the result
variable gets dropped before from_str()
is done with the value, but I was unable to get 'just the slice' with the value. I've tried as_str()
, &*
, &'static str
and several other options to try to make this work, but I'm clearly missing something, as it seems like a basic use-case. I must admit I'm still a bit fuzzy on 'lifetime' and the involved generics, so the problem might be there.
Upvotes: 1
Views: 387
Reputation: 117846
I would suggest you to read Understanding deserializer lifetimes from the serde manual. There they suggest T: DeserializeOwned
, explicitly mentioning your usecase:
Usually this is because the data that is being deserialized from is going to be thrown away before the function returns, so
T
must not be allowed to borrow from it.
So the solution is:
use serde::de::DeserializeOwned;
pub fn read_data_from_json<T: DeserializeOwned, P: AsRef<Path>>(path: P) -> T {
let result = std::fs::read_to_string(path).unwrap();
return serde_json::from_str(&result).unwrap();
}
Upvotes: 4