【问题标题】:How can I accept multiple deserialization names for the same Serde field?如何为同一个 Serde 字段接受多个反序列化名称?
【发布时间】:2019-01-11 15:56:59
【问题描述】:

我正在尝试使用 Serde 根据以下结构反序列化 JSON (serde-json) 和 XML (serde-xml-rs) 文件:

use serde_derive::Deserialize;

#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct SchemaConfig {
    pub name: String,
    #[serde(rename = "Cube")]
    pub cubes: Vec<CubeConfig>,
}

我要反序列化的字段根据文件类型具有不同的名称。在这种情况下,我希望 JSON 文件有一个带有多维数据集列表的 cubes 键,但 XML 中的等价物将是多个 &lt;Cube /&gt; 元素。

我不知道如何同时接受 cubesCube 作为反序列化的键。我发现最接近的是 #[serde(rename = "Cube")] 选项,但是当我使用它时,JSON 反序列化停止工作,因为它只接受 Cube 键。如果我删除该选项,XML 反序列化将停止工作,因为它只接受 cubes 作为键。

在 Serde 中是否有一种简单的方法来完成此任务?

【问题讨论】:

    标签: rust serde serde-json


    【解决方案1】:

    我鼓励您阅读 Serde 文档。 field attributes章节介绍alias attribute,重点是我的:

    #[serde(alias = "name")]

    从给定名称或其 Rust 名称反序列化此字段。可能 重复以指定同一字段的多个可能名称

    use serde::Deserialize; // 1.0.88
    use serde_json; // 1.0.38
    
    #[derive(Debug, Deserialize)]
    struct SchemaConfig {
        #[serde(alias = "fancy_square", alias = "KUBE")]
        cube: [i32; 3],
    }
    
    fn main() -> Result<(), Box<std::error::Error>> {
        let input1 = r#"{
            "fancy_square": [1, 2, 3]
        }"#;
    
        let input2 = r#"{
            "KUBE": [4, 5, 6]
        }"#;
    
        let one: SchemaConfig = serde_json::from_str(input1)?;
        let two: SchemaConfig = serde_json::from_str(input2)?;
    
        println!("{:?}", one);
        println!("{:?}", two);
    
        Ok(())
    }
    

    我希望 JSON 文件有一个带有多维数据集列表的 cubes 键,但 XML 中的等价物将是多个 &lt;Cube /&gt; 元素。

    这听起来确实像是您希望文件有两种不同的结构。在这种情况下,请查看以下内容:

    【讨论】:

    • 感谢您提供代码示例。我确实阅读了文档,但从文档中我不清楚如何指定多个 alias 值。您的代码示例在这里非常清楚。 ?
    • 这看起来是唯一的解决方法。但它有问题。想想fancy_squareKUBE可以在同一个文件里,也可以在不同的文件里。
    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 2023-01-08
    • 2019-11-02
    • 1970-01-01
    • 2019-11-25
    相关资源
    最近更新 更多