Crates.io | serde-persistent-deserializer |
lib.rs | serde-persistent-deserializer |
version | 0.3.0 |
source | src |
created_at | 2024-10-27 17:58:16.433615 |
updated_at | 2024-10-30 03:37:21.316172 |
description | A wrapper for persistent Serde deserializers |
homepage | |
repository | https://github.com/fjarri/serde-persistent-deserializer |
max_upload_size | |
id | 1424852 |
size | 18,146 |
serde
deserializersWhen one writes an implementation of serde::Deserializer
for their format, it is commonly written for a &mut
of some type, or a wrapper of it --- because it has to be recursively passed down when deserializing nested structs, lists, and so on.
But if someone else wants to be generic over types that implement Deserializer
(e.g. when using the erased-serde
crate), it necessarily produces higher-ranked bounds on lifetimes (something along the lines of for<'a, 'de> &'a mut D: Deserializer<'de>
), which cannot be encapsulated in a trait and will be propagated to all dependent generic code (a current limitation of Rust; see https://github.com/rust-lang/rust/issues/50346 and other related issues). Also, using erased_serde::Deserializer::erase
on serde::Deserializer
types in a real world code is not trivial (see https://github.com/dtolnay/erased-serde/issues/107 for an example).
To amend that, it would be convenient to additionally implement serde::Deserializer
on the object itself, which involves writing a long sheet of boilerplate like
struct MyDeserializerRef<'a, 'de> {
de: &'a mut MyDeserializer<'de>
}
impl<'a, 'de> Deserializer<'de> for MyDeserializerRef<'a, 'de> {
// ... actual deserialization logic here
}
impl<'de> MyDeserializer<'de> {
fn as_transient_deserializer<'a>(&'a mut self) -> MyDeserializerRef<'a, 'de> { ... }
}
impl<'de> Deserializer<'de> for MyDeserializer<'de> {
fn deserialize_any<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error>
{
self.as_transient_deserializer().deserialize_any(visitor)
}
fn deserialize_bool<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error>
{
self.as_transient_deserializer().deserialize_bool(visitor)
}
// ... and dozens more methods with the same content
}
This crate instead requires one to only provide an implementation of AsTransientDeserializer
for their type, and then the PersistentDeserializer
wrapper will automatically derive serde::Deserializer
.