Как мне сериализовать или десериализовать дугу<T> в Серде?

У меня есть структура, которая содержит детей своего собственного типа. Эти дети завернуты в Arcс, и у меня возникают проблемы при звонке serde_json::to_string в теме. Моя структура:

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

Это приводит к ошибке the trait 'serde::Serialize' is not implemented for 'std::sync::Arc<db::queries::categories::Category>' Я попробовал несколько различных подходов, чтобы заставить сериализацию работать, такую ​​как:

#[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()
}

Это не помогает, так как я получаю ту же ошибку. Я также попробовал:

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();
    }
}

но это дает ошибку impl doesn't use types inside crate

Я мог бы, вероятно, жить без десериализации, так как на этом этапе сериализация важнее.

1 ответ

Решение

Serde предоставляет реализации Serialize а также Deserialize за Arc<T> а также Rc<T>, но только если rc функция включена.

На справочном сайте Серде есть комментарий , объясняющий почему:

Выбираю impls для Rc<T> а также Arc<T>, Сериализация и десериализация этих типов не сохраняет идентичность и может привести к нескольким копиям одних и тех же данных. Убедитесь, что это то, что вы хотите, прежде чем включить эту функцию.

Чтобы включить rc функция, вы должны спросить об этом по-своему Cargo.toml:

[dependencies]
serde = { version = "1.0", features = ["rc"] }
Другие вопросы по тегам