Hello. I am trying to create a library for parsing LabVIEW binary files. Since LabVIEW does have containers like clusters and arrays it is only logical to create serde deserializer as well. So far creating one was fairly simple, except for one thing: I do not understand how to write SeqAccess
implementation as my attempts ended with one lifetime-related error or another. On other hand, bincode authors have somehow managed to do just that so I ended up trying to duplicate their code without really understanding it.
So the question is, why bincode code manages to compile, but very similar my fails with
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src\deserialize.rs:164:38
|
164 | seed.deserialize(&mut *self.deserializer).map(Some)
| ^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 151:19...
--> src\deserialize.rs:151:19
|
151 | impl<'de, 'a, 'b: 'a, P: LVParseLiving<'de> + 'b> SeqAccess<'de>
| ^^
note: ...so that reference does not outlive borrowed content
--> src\deserialize.rs:164:38
|
164 | seed.deserialize(&mut *self.deserializer).map(Some)
| ^^^^^^^^^^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'de as defined on the impl at 151:14...
--> src\deserialize.rs:151:14
|
151 | impl<'de, 'a, 'b: 'a, P: LVParseLiving<'de> + 'b> SeqAccess<'de>
| ^^^
= note: ...so that the types are compatible:
expected serde::Deserializer<'de>
found serde::Deserializer<'_>
For reference, here is the relevant code:
pub trait LVParse {
…
}
trait LVParseLiving<'a>: LVParse {
}
/// `LVDeserializer` describes serde deserializer.
struct LVDeserializer<P> {
/// Some data reader for which parsing was implemented.
parser: P,
}
macro_rules! create_deserialize {
…
($fname:ident, $de:tt => $self:ident, $v:ident : $vt:ty, $visitor:ident
$code:block) => {
fn $fname<V: Visitor<$de>>($self, $v: $vt, $visitor: V)
-> LVResult<V::Value>
$code
};
…
}
impl<'de, P: LVParseLiving<'de>> Deserializer<'de>
for &'de mut LVDeserializer<P>
{
type Error = LVError;
…
create_deserialize!(deserialize_tuple, 'de => self, size: usize, visitor {
/// `LVArray` describes serde sequence.
struct LVArray<'a, P: LVParse + 'a> {
deserializer: &'a mut LVDeserializer<P>,
size: u32,
}
impl<'de, 'a, 'b: 'a, P: LVParseLiving<'de> + 'b> SeqAccess<'de>
for LVArray<'a, P>
{
type Error = LVError;
fn next_element_seed<T>(&mut self, seed: T)
-> LVResult<Option<T::Value>>
where T: DeserializeSeed<'de>
{
if self.size == 0 {
Ok(None)
} else {
self.size -= 1;
seed.deserialize(&mut *self.deserializer).map(Some)
}
}
fn size_hint(&self) -> Option<usize> {
Some(self.size as usize)
}
}
visitor.visit_seq(LVArray {
deserializer: self,
size: size as u32,
})
});
…
}