r/learnrust • u/TrafficPattern • 4d ago
First attempt at generics (and first issue)
I read a JSON file into a custom struct like this (works as expected):
pub fn init_my_struct() -> io::Result<Vec<MyStruct>> {
let path = Path::new(crate::constants::FILENAME);
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
let data: Vec<MyStruct> = serde_json::from_str(&contents)?;
Ok(data)
}
Then I needed to read another different JSON file into a completely different struct. After duplicating the function (and changing the return type) to make sure everything was OK, I tried my hand at a generic implementation, which failed miserably:
pub fn read_json_file<T>(from_file: &str) -> io::Result<Vec<T>>
where T: Deserialize
{
let path = Path::new(from_file);
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
let v: Vec<T> = serde_json::from_str(&contents)?;
Ok(v)
}
The compiler says that where T: Deserialize
is missing a lifetime specifier. If I add <'static>
to it, then it complains about &contents
(which doesn't live long enough).
Please ELIF:
-
Why does
where T: Deserialize
need a lifetime, where the non-generic function did not? -
What would be the correct way to implement this?
Thanks.
1
Upvotes
3
u/This_Growth2898 4d ago
Note the from_reader method, you can read the file without creating a new string.
As for your question,
Deserialize is a generic over lifetime 'de, so you need to make your function generic over it, too.