How to borrow a field for serialization but create it during deserialization?

自闭症网瘾萝莉.ら 提交于 2021-01-27 19:27:02

问题


I have a struct like this:

#[derive(Serialize, Deserialize)]
struct Thing {
    pub small_header: Header,
    pub big_body: Body,
}

I want to serialize this Thing to send over the network. I already have a Body available but I can't move it (imagine I am doing something with it, and every now and then I receive a command to temporarily stop what I'm doing and send over whatever data I have now) and I can't copy it (it's too big, possibly hundreds of megabytes).

So I'd like Serde to just borrow the one I have for serializing it, since it shouldn't need to be moved into a struct for that. If I rewrite Thing to take a reference, I obviously can't derive Deserialize!

The workaround I've been using is just using an Arc<Body> in my code, so that I can work with the body in my normal logic and when I need to serialize it, I can just do a cheap clone and put the Arc<Body> into the struct for serialization. During deserialization Serde will make a new Arc with a refcount of 1.

This still involves scattering Arc all over my code, which isn't great, not to mention the unnecessary (though minor) runtime cost. What is the correct solution for this use case?

The funny thing is that if I didn't have to send a header, then this would be a non-issue since I could serialize by reference and deserialize by value, but the presence of a header makes this impossible. I feel like I'm missing something about how Serde borrows data here...


回答1:


You could use a Cow, which will be Cow::Borrowed when serializing and will deserialize as Cow::Owned when deserializing.

use std::borrow::Cow;

#[derive(Serialize, Deserialize)]
struct Thing<'a> {
    small_header: Header,
    big_body: Cow<'a, Body>,
}

Alternatively, you could serialize and deserialize as two independent data structures.

#[derive(Serialize)]
struct SerializeThing<'a> {
    small_header: Header,
    big_body: &'a Body,
}

#[derive(Deserialize)]
struct DeserializeThing {
    small_header: Header,
    big_body: Body,
}


来源:https://stackoverflow.com/questions/52733047/how-to-borrow-a-field-for-serialization-but-create-it-during-deserialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!