#deserializer #persistent #object #produces

no-std serde-persistent-deserializer

A wrapper for persistent Serde deserializers

3 releases (breaking)

0.3.0 Oct 30, 2024
0.2.0 Oct 27, 2024
0.1.0 Oct 27, 2024

#672 in Encoding

Download history 500/week @ 2024-10-24 136/week @ 2024-10-31 110/week @ 2024-11-07 336/week @ 2024-11-14 40/week @ 2024-11-21 90/week @ 2024-11-28 128/week @ 2024-12-05 127/week @ 2024-12-12

390 downloads per month
Used in manul

MIT license

15KB
232 lines

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.

Dependencies

~100–335KB