在 Rust 中使用可选的 JSON 字段,避免在 JSON 中使用 None / null,而是使用 undefined

Working with optional JSON fields in Rust, avoid None / null in JSON, use undefined instead

有没有比这个更好(更精简)的表达方式:

#[derive(Serialize, Deserialize, Debug, Default]
pub struct PagingObject {
  #[serde(skip_serializing_if = "Option::is_none")]
  offsetId: Option<String>,     // offset expressed as element id (uuid)
  #[serde(skip_serializing_if = "Option::is_none")]
  offset: Option<i32>,          // offset expressed as index (numeric)
  #[serde(skip_serializing_if = "Option::is_none")]
  total: Option<i32>,           // total number of elements
  #[serde(skip_serializing_if = "Option::is_none")]
  totalPages: Option<i32>,      // total number of pages based on limit
  #[serde(skip_serializing_if = "Option::is_none")]
  previous: Option<String>,     // link to previous page
  #[serde(skip_serializing_if = "Option::is_none")]
  next: Option<String>,         // link to next page
  #[serde(skip_serializing_if = "Option::is_none")]
  limit: Option<i32>            // the limit used
}

serde 没有任何 built-in 方法来处理这个问题。但是,third-party serde_with::skip_serializing_none 宏解决了这个问题。用法很简单,就是在派生前加一个属性。

#[serde_with::skip_serializing_none]
#[derive(Serialize, Deserialize, Debug, Default]
pub struct PagingObject {
  offsetId: Option<String>,     // offset expressed as element id (uuid)
  offset: Option<i32>,          // offset expressed as index (numeric)
  total: Option<i32>,           // total number of elements
  totalPages: Option<i32>,      // total number of pages based on limit
  previous: Option<String>,     // link to previous page
  next: Option<String>,         // link to next page
  limit: Option<i32>            // the limit used
}