Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

rust - How do I serialize or deserialize an Arc<T> in Serde?

I have a struct that contains children of its own type. These children are wrapped in Arcs, and I'm getting issues when calling serde_json::to_string on it. My struct is:

#[derive(Serialize, Deserialize)]
pub struct Category {
    pub id: i32,
    pub name: String,
    pub parent_id: i32,
    pub children: Vec<Arc<Category>>,
}

This produces the error the trait 'serde::Serialize' is not implemented for 'std::sync::Arc<db::queries::categories::Category>' I've tried a few different approaches to get serialization working, such as:

#[serde(serialize_with = "arc_category_vec")]
pub children: Vec<Arc<Category>>
fn arc_category_vec<S>(value: &Vec<Arc<Category>>, serializer: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    let mut seq = serializer.serialize_seq(Some(value.len()))?;
    for e in value {
        seq.serialize_element(e.as_ref())?;
    }
    seq.end()
}

This doesn't help as I get the same error. I also tried:

impl Serialize for Arc<Category> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut state = serializer.serialize_struct("Category", 4)?;

        state.serialize_field("id", &self.id)?;
        state.serialize_field("name", &self.name)?;
        state.serialize_field("parent_id", &self.parent_id)?;
        state.serialize_field("children", &self.children)?;
        state.end();
    }
}

but that gives the error impl doesn't use types inside crate

I could probably live without deserialization, since serialization is more important at this point.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Serde provides implementations of Serialize and Deserialize for Arc<T> and Rc<T>, but only if the rc feature is enabled.

There's a comment on Serde's reference website explaining why:

Opt into impls for Rc<T> and Arc<T>. Serializing and deserializing these types does not preserve identity and may result in multiple copies of the same data. Be sure that this is what you want before enabling this feature.

To enable the rc feature, you need to ask for it in your own Cargo.toml:

[dependencies]
serde = { version = "1.0", features = ["rc"] }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...