I'm deserialising using Serde and I want to take advantage of the zero-copy functionality while using a streaming iterator which returns a reference to the current value. This reference is valid until advance
is called on the iterator.
use serde::Deserialize;
use streaming_iterator::StreamingIterator;
struct Iterator<'i> {
owned_value: String,
message: Option<Message<'i>>
}
#[derive(Deserialize, Debug)]
struct Message<'i> {
content: &'i str
}
fn convert<'c>(input: &'c str) -> Message<'c> {
serde_json::from_str(input).unwrap()
}
impl<'i> StreamingIterator for Iterator<'i> {
type Item = Message<'i>;
fn advance(&mut self) {
self.message = Some(convert(&self.owned_value))
}
fn get(&self) -> Option<&Self::Item> {
Some(&self.message.unwrap())
}
}
fn main() {
let data = r#"
{
"content": "Hello world",
}"#;
let iter = Iterator{owned_value: String::from(data), message: None};
println!("{}", iter.get().unwrap().content);
}
cargo.toml
[dependencies]
serde = {version = "1.0", features = ["derive"]}
serde_json = "1.0"
streaming-iterator = "0.1.4"
The compiler complains
cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src\main.rs:22:37
|
22 | self.message = Some(convert(&self.owned_value))
| ^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 21:5...
--> src\main.rs:21:5
|
21 | / fn advance(&mut self) {
22 | | self.message = Some(convert(&self.owned_value))
23 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src\main.rs:22:37
|
22 | self.message = Some(convert(&self.owned_value))
| ^^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'i as defined on the impl at 18:6...
--> src\main.rs:18:6
|
18 | impl<'i> StreamingIterator for Iterator<'i> {
| ^^
= note: ...so that the expression is assignable:
expected std::option::Option<Message<'i>>
found std::option::Option<Message<'_>>
From what I can tell, this is because the compiler is unable to prove that a reference to self
will last long enough
Is what I am trying to do possible? Is there a way I can prove to the borrow checker that as long as there is a reference to self then any references returned from get
are valid?