I am fairly unfamiliar with Rust lifetime. Here is the code I wrote:
pub fn from_reader<'de, T, R>(reader: &'de mut R) -> Result<T>
where
T: Deserialize<'de>,
R: Read,
{
let mut reader = BufReader::new(reader);
from_buf_reader(&mut reader)
}
pub fn from_buf_reader<'de, T, R>(reader: &'de mut R) -> Result<T>
where
T: Deserialize<'de>,
R: BufRead,
{
//...
}
I got the following error:
error[E0597]: `reader` does not live long enough
--> src/de.rs:34:21
|
28 | pub fn from_reader<'de, T, R>(reader: &'de mut R) -> Result<T>
| --- lifetime `'de` defined here
...
34 | from_buf_reader(&mut reader)
| ----------------^^^^^^^^^^^-
| | |
| | borrowed value does not live long enough
| argument requires that `reader` is borrowed for `'de`
35 | }
| - `reader` dropped here while still borrowed
From my understanding, the newly created reader
needs to have 'de
lifetime, which is not possible because 'de
begins before this function is even called. Is this the correct interpretation?
Is there a way around this issue without directly taking ownership of the parameter?
In Serde, Deserialize<'de>
means "deserialize into a structure which borrows from data with the lifetime 'de
."
'de
.'de
.That input which must live is not reader
; it is the bytes that are read. You cannot use a lifetime that predates the bytes actually getting read.
If you're trying to perform zero-copy deserialization, you must read the bytes into a buffer and keep them around until you're done with the value.
If you just want a function with approximately the signature you have, then use DeserializeOwned
instead of Deserialize<'de>
— that requires the deserialized value to not borrow from the input, so its lifetime is independent of the input.