6

我有一个带有 serde 注释的结构树,它成功地解析了示例 XML,包括这个片段:

<bmsg>
    <cmsg>
         <!-- ... -->
    <cmsg>
<bmsg>

现在我正在使用一个大型示例 XML 文件进行测试,并且以下结构失败,因为有时<cmsg>..</cmsg>会丢失。我正在使用以下方法反序列化:

#[derive(Serialize,Deserialize, Debug)]
struct A {  
    #[serde(rename="bmsg")]
    messages: B,                 // <====
}

#[derive(Serialize,Deserialize, Debug)]
struct B {  // bmsg
    #[serde(rename="cmsg")]
    list: Vec<C>,
}

这导致了第二个结构中的错误:

panicked at 'called `Result::unwrap()` on an `Err` value: missing field `cmsg`

我将第一个结构更改为具有 aVec<>以便它可以处理可选元素:

#[derive(Serialize,Deserialize, Debug)]
struct A {  
    #[serde(rename="bmsg")]
    messages: Vec<B>,            // <====
}

#[derive(Serialize,Deserialize, Debug)]
struct B {  // bmsg
    #[serde(rename="cmsg")]
    list: Vec<C>,
}

但是 serde 继续给出同样的错误。我也试过Option<>,但没有成功。

最让我困惑的是,我到处使用Vec<>,从来没有遇到过这个问题。

4

1 回答 1

8

这似乎Option<T>意味着该项目确实存在,它只是没有内容。

该文档似乎建议使用default属性,以告诉反序列化器在无法找到该类型时使用该Default特征的实现。

考虑到这一点,也许这对你有用:

#[derive(Serialize,Deserialize, Debug)]
struct A {  
    #[serde(rename = "bmsg")]
    messages: B,
}

#[derive(Serialize,Deserialize, Debug)]
struct B {  // bmsg
    #[serde(rename = "cmsg", default)] // <----- use default to call `Default::default()` against this vector
    list: Vec<C>,
}

你可以在 Playground 中找到我用来检查这个的代码。它不会在 Playground 中运行,但会在本地运行时产生您预期的结果。

于 2017-10-05T12:41:10.853 回答