serde-persistent-deserializer

Crates.ioserde-persistent-deserializer
lib.rsserde-persistent-deserializer
version0.3.0
sourcesrc
created_at2024-10-27 17:58:16.433615
updated_at2024-10-30 03:37:21.316172
descriptionA wrapper for persistent Serde deserializers
homepage
repositoryhttps://github.com/fjarri/serde-persistent-deserializer
max_upload_size
id1424852
size18,146
Bogdan Opanchuk (fjarri)

documentation

README

A wrapper for persistent serde deserializers

crate Docs License Build Status Coverage

When 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.

Commit count: 10

cargo fmt