You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When writing a Deserializer impl, it is commonly written for &mut of something, or a wrapper of it - because it has to be recursively passed down when deserializing nested structs, lists, and so on.
But if the user code wants to be generic over types that implement Deserializer (e.g. when using erased-serde, see my use case in dtolnay/erased-serde#107), it necessarily produces higher-ranked bounds on lifetimes (e.g. for<'a, 'de> &'a mut S::Des<'de>: serde::Deserializer<'de> in the quoted example), which cannot be encapsulated in a trait and will be propagated to all dependent generic code (current limitation of Rust; see rust-lang/rust#50346 and other related issues).
To amend that, it would be convenient to impl Deserializer on the object itself, which involves writing a long sheet of boilerplate like
structMyDeserializerRef<'a,'de>{de:&'a mutMyDeserializer<'de>}impl<'a,'de>Deserializer<'de>forMyDeserializerRef<'a,'de>{// ... actual deserialization logic}impl<'de>MyDeserializer<'de>{fnas_mut<'a>(&'a mutself) -> MyDeserializerRef<'a,'de>{ ...}}impl<'de>Deserializer<'de>forMyDeserializer<'de>{fndeserialize_any<V>(mutself,visitor:Visitor<'de>) -> Result<V::Value,Self::Error>{self.as_mut().deserialize_any(visitor)}fndeserialize_bool<V>(mutself,visitor:Visitor<'de>) -> Result<V::Value,Self::Error>{self.as_mut().deserialize_bool(visitor)}// ... and dozens more methods with the same content}
Is there some easier way to do that? Is a macro necessary?
The text was updated successfully, but these errors were encountered:
It seems like no macro is required, but there's still a significant amount of boilerplate. I made a standalone crate that does this kind of wrapping: https://github.com/fjarri/serde-persistent-deserializer. Is it something you would potentially want to see included in serde?
Shipping it in a separate crate seems best to me. It's not a totally common use case, and you can do major bumps if you want to change entirely how it's done.
Ideally we'd just have a blanket impl, but that's a breaking change now if it ever was possible at all
When writing a
Deserializer
impl, it is commonly written for&mut
of something, or a wrapper of it - because it has to be recursively passed down when deserializing nested structs, lists, and so on.But if the user code wants to be generic over types that implement
Deserializer
(e.g. when usingerased-serde
, see my use case in dtolnay/erased-serde#107), it necessarily produces higher-ranked bounds on lifetimes (e.g.for<'a, 'de> &'a mut S::Des<'de>: serde::Deserializer<'de>
in the quoted example), which cannot be encapsulated in a trait and will be propagated to all dependent generic code (current limitation of Rust; see rust-lang/rust#50346 and other related issues).To amend that, it would be convenient to impl
Deserializer
on the object itself, which involves writing a long sheet of boilerplate likeIs there some easier way to do that? Is a macro necessary?
The text was updated successfully, but these errors were encountered: