【问题标题】:How to serialize a struct with a top-level key with Serde?如何使用 Serde 序列化具有顶级键的结构?
【发布时间】:2021-07-15 15:08:15
【问题描述】:

我目前正在使用 Rocket 开发一个 Web API,它使用以下结构来响应错误:

#[derive(Serialize, Deserialize)]
pub struct ErrorResponse {
    code: u16,
    reason: &'static str,
    #[serde(skip_serializing_if = "Option::is_none")]
    description: Option<String>,
}

实际上,序列化这个结构会产生类似这样的json:

{
  "code": 400,
  "reason": "Bad Request"
}

我希望以这种方式对其进行序列化:

{
  "error": {
    "code": 400,
    "reason": "Bad Request"
  }
}

不使用两种不同结构的最简单方法是什么?

提前感谢您的帮助!

【问题讨论】:

  • 除非您为它实现自己的序列化/反序列化,否则我不确定它是否可行。

标签: rust serde


【解决方案1】:

我能想到的最简单的方法是将你的结构包装在一个带有单个结构变体的 enum 中:

#[derive(Serialize, Deserialize)]
pub enum ErrorResponseWrapper {
    #[serde(rename = "error")]
    ErrorResponse {
        code: u16,
        reason: &'static str,
        #[serde(skip_serializing_if = "Option::is_none")]
        description: Option<String>,
    }
}

这很烦人的是类型和构造函数现在必须有不同的名称。 IE。如果一个函数采用ErrorResponse,它现在必须采用ErrorResponseWrapper(尽管您可能想想出一个比这更好的名称),但您必须使用ErrorResponseWrapper::ErrorResponse 变体构造这样的值。幸运的是,您至少可以将 use ErrorResponseWrapper::ErrorResponse; 添加到您的导入中。

Playground

【讨论】:

  • 很好,也许他只能重新导出错误响应,就是这样。
  • 好主意,我没想到把它变成一个枚举。感谢您的快速答复!
猜你喜欢
  • 1970-01-01
  • 2017-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
相关资源
最近更新 更多