Deserialization in place


I’m trying to implement a function whose signature would be something similar to

fn deserialize_in_place(data: *mut SomeData, output: *mut Foo) {
    // build a serde::Deserializer out of data
    // deserialize into output

The signature is pretty much fixed by FFI. Foo is not generic here because of FFI, but is generic in the enclosing scope, with a bound of Default + whatever I need to make it deserializable.
Since Serde expects to create the output struct by itself, I can’t use normal Deserialize trait. I could, I believe, deserialize into a new object and move that inside output, but that would mean creating a new object every time, with potential repeated allocations (I can’t borrow from data either, as its lifetime is unknown), which are unwanted as this function would be called very often.

Looking inside Serde it appears that the Deserialize trait has a second function, deserialize_in_place, which has the exact signature I require, but they also explain that it’s usually not what you want. Furthermore it seems that the macros in serde-derive do not implement that function and rely on the default implementation (which is exactly what I mentioned before, moving inside the output reference), meaning that by default any struct where I don’t implement serde::Deserialize by myself won’t be able to use that properly, even if for most standard collections for example there is already an implementation, as every recursive call will be to plain deserialize. Or is it something for Deserializers to use?

Is there a way to do this with Serde? Am I looking at the right function?

Thanks in advance


Just to check: deserialize_in_place needs a feature to be activated. Have you done so?

From the release note:

Enable the deserialize_in_place feature of serde_derive to generate these efficient implementations for all types that use #[derive(Deserialize)].


I didn’t. This solves the problem I guess. Thanks a lot.

I stumbled upon the function completely by chance while looking at the Deserialize docs for Vec (and not from the release notes), since it’s marked as hidden inside the trait, so there was not mention at all about the serde_derive feature.

Thanks for the help